Skip to content

Commit 8032159

Browse files
Merge pull request #2394 from BerriAI/litellm_faster_api_key_checking
fix(proxy_server.py): use argon2 for faster api key checking
2 parents 86fe7a9 + c022568 commit 8032159

File tree

7 files changed

+147
-43
lines changed

7 files changed

+147
-43
lines changed

.circleci/config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ jobs:
4545
pip install "asyncio==3.4.3"
4646
pip install "apscheduler==3.10.4"
4747
pip install "PyGithub==1.59.1"
48+
pip install argon2-cffi
4849
pip install python-multipart
4950
- save_cache:
5051
paths:

litellm/proxy/proxy_server.py

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
import importlib
1010
import warnings
1111
import backoff
12+
from argon2 import PasswordHasher
13+
14+
ph = PasswordHasher()
1215

1316

1417
def showwarning(message, category, filename, lineno, file=None, line=None):
@@ -257,6 +260,7 @@ async def openai_exception_handler(request: Request, exc: ProxyException):
257260
ui_access_mode: Literal["admin", "all"] = "all"
258261
proxy_budget_rescheduler_min_time = 597
259262
proxy_budget_rescheduler_max_time = 605
263+
litellm_master_key_hash = None
260264
### INITIALIZE GLOBAL LOGGING OBJECT ###
261265
proxy_logging_obj = ProxyLogging(user_api_key_cache=user_api_key_cache)
262266
### REDIS QUEUE ###
@@ -336,31 +340,36 @@ async def user_api_key_auth(
336340
Unprotected endpoints
337341
"""
338342
return UserAPIKeyAuth()
343+
elif route.startswith("/config/"):
344+
raise Exception(f"Only admin can modify config")
339345

340346
if api_key is None: # only require api key if master key is set
341347
raise Exception(f"No api key passed in.")
342348

343-
if secrets.compare_digest(api_key, ""):
349+
if api_key == "":
344350
# missing 'Bearer ' prefix
345351
raise Exception(
346352
f"Malformed API Key passed in. Ensure Key has `Bearer ` prefix. Passed in: {passed_in_key}"
347353
)
348354

349355
### CHECK IF ADMIN ###
350356
# note: never string compare api keys, this is vulenerable to a time attack. Use secrets.compare_digest instead
351-
is_master_key_valid = secrets.compare_digest(api_key, master_key)
357+
try:
358+
is_master_key_valid = ph.verify(litellm_master_key_hash, api_key)
359+
except Exception as e:
360+
is_master_key_valid = False
361+
352362
if is_master_key_valid:
353363
return UserAPIKeyAuth(
354364
api_key=master_key,
355365
user_role="proxy_admin",
356366
user_id=litellm_proxy_admin_name,
357367
)
368+
358369
if isinstance(
359370
api_key, str
360371
): # if generated token, make sure it starts with sk-.
361372
assert api_key.startswith("sk-") # prevent token hashes from being used
362-
if route.startswith("/config/") and not is_master_key_valid:
363-
raise Exception(f"Only admin can modify config")
364373

365374
if (
366375
prisma_client is None and custom_db_client is None
@@ -1494,7 +1503,7 @@ async def load_config(
14941503
"""
14951504
Load config values into proxy global state
14961505
"""
1497-
global master_key, user_config_file_path, otel_logging, user_custom_auth, user_custom_auth_path, user_custom_key_generate, use_background_health_checks, health_check_interval, use_queue, custom_db_client, proxy_budget_rescheduler_max_time, proxy_budget_rescheduler_min_time, ui_access_mode
1506+
global master_key, user_config_file_path, otel_logging, user_custom_auth, user_custom_auth_path, user_custom_key_generate, use_background_health_checks, health_check_interval, use_queue, custom_db_client, proxy_budget_rescheduler_max_time, proxy_budget_rescheduler_min_time, ui_access_mode, litellm_master_key_hash
14981507

14991508
# Load existing config
15001509
config = await self.get_config(config_file_path=config_file_path)
@@ -1759,6 +1768,9 @@ async def load_config(
17591768
)
17601769
if master_key and master_key.startswith("os.environ/"):
17611770
master_key = litellm.get_secret(master_key)
1771+
1772+
if master_key is not None and isinstance(master_key, str):
1773+
litellm_master_key_hash = ph.hash(master_key)
17621774
### CUSTOM API KEY AUTH ###
17631775
## pass filepath
17641776
custom_auth = general_settings.get("custom_auth", None)
@@ -2837,6 +2849,7 @@ async def chat_completion(
28372849
response = await proxy_logging_obj.post_call_success_hook(
28382850
user_api_key_dict=user_api_key_dict, response=response
28392851
)
2852+
28402853
return response
28412854
except Exception as e:
28422855
traceback.print_exc()
@@ -7032,42 +7045,45 @@ async def health_endpoint(
70327045
else, the health checks will be run on models when /health is called.
70337046
"""
70347047
global health_check_results, use_background_health_checks, user_model
7048+
try:
7049+
if llm_model_list is None:
7050+
# if no router set, check if user set a model using litellm --model ollama/llama2
7051+
if user_model is not None:
7052+
healthy_endpoints, unhealthy_endpoints = await perform_health_check(
7053+
model_list=[], cli_model=user_model
7054+
)
7055+
return {
7056+
"healthy_endpoints": healthy_endpoints,
7057+
"unhealthy_endpoints": unhealthy_endpoints,
7058+
"healthy_count": len(healthy_endpoints),
7059+
"unhealthy_count": len(unhealthy_endpoints),
7060+
}
7061+
raise HTTPException(
7062+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
7063+
detail={"error": "Model list not initialized"},
7064+
)
70357065

7036-
if llm_model_list is None:
7037-
# if no router set, check if user set a model using litellm --model ollama/llama2
7038-
if user_model is not None:
7066+
### FILTER MODELS FOR ONLY THOSE USER HAS ACCESS TO ###
7067+
if len(user_api_key_dict.models) > 0:
7068+
allowed_model_names = user_api_key_dict.models
7069+
else:
7070+
allowed_model_names = [] #
7071+
if use_background_health_checks:
7072+
return health_check_results
7073+
else:
70397074
healthy_endpoints, unhealthy_endpoints = await perform_health_check(
7040-
model_list=[], cli_model=user_model
7075+
llm_model_list, model
70417076
)
7077+
70427078
return {
70437079
"healthy_endpoints": healthy_endpoints,
70447080
"unhealthy_endpoints": unhealthy_endpoints,
70457081
"healthy_count": len(healthy_endpoints),
70467082
"unhealthy_count": len(unhealthy_endpoints),
70477083
}
7048-
raise HTTPException(
7049-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
7050-
detail={"error": "Model list not initialized"},
7051-
)
7052-
7053-
### FILTER MODELS FOR ONLY THOSE USER HAS ACCESS TO ###
7054-
if len(user_api_key_dict.models) > 0:
7055-
allowed_model_names = user_api_key_dict.models
7056-
else:
7057-
allowed_model_names = [] #
7058-
if use_background_health_checks:
7059-
return health_check_results
7060-
else:
7061-
healthy_endpoints, unhealthy_endpoints = await perform_health_check(
7062-
llm_model_list, model
7063-
)
7064-
7065-
return {
7066-
"healthy_endpoints": healthy_endpoints,
7067-
"unhealthy_endpoints": unhealthy_endpoints,
7068-
"healthy_count": len(healthy_endpoints),
7069-
"unhealthy_count": len(unhealthy_endpoints),
7070-
}
7084+
except Exception as e:
7085+
traceback.print_exc()
7086+
raise e
70717087

70727088

70737089
@router.get(

litellm/proxy/tests/large_text.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
text = """
2+
{{Short description|Military commander and king of Macedon (356–323 BC)}}
3+
{{About|the ancient king of Macedonia}}
4+
{{Good article}}
5+
{{pp-semi-indef}}
6+
{{pp-move-indef}}
7+
{{Use Oxford spelling|date=September 2020}}
8+
{{Use dmy dates|date=January 2023}}
9+
{{Infobox royalty
10+
| name = Alexander the Great
11+
| title = [[Basileus]]
12+
| image = Alexander the Great mosaic (cropped).jpg
13+
| caption = Alexander in the ''[[Alexander Mosaic]]''
14+
| succession = [[King of Macedon]]
15+
| reign = 336–323 BC
16+
| predecessor = [[Philip II of Macedon|Philip II]]
17+
| successor = {{hlist|
18+
| [[Alexander IV of Macedon|Alexander IV]]
19+
| [[Philip III of Macedon|Philip III]]
20+
}}
21+
| succession2 = [[Hegemony#8th–1st centuries BC|Hegemon]] of the [[League of Corinth|Hellenic League]]
22+
| reign2 = 336–323 BC
23+
| predecessor2 = Philip II
24+
| successor2 = [[Demetrius I of Macedon]]
25+
| succession3 = [[List of pharaohs|Pharaoh of Egypt]]
26+
| reign3 = 332–323 BC
27+
| predecessor3 = [[Darius III]]
28+
| successor3 = {{hlist|
29+
| Alexander IV
30+
| Philip III
31+
{{Ancient Egyptian royal titulary case |nomen={{ubl|{{transliteration|egy|ꜣrwksjndrs}}|{{transliteration|egy|Aluksindres}}|Alexandros}} |nomen_hiero=<hiero>A-rw:k:z-i-n:d:r:z</hiero> |horus={{ubl|{{transliteration|egy|mk-kmt}}|{{transliteration|egy|Mekemet}}|Protector of Egypt}} {{Infobox pharaoh/Serekh |Horus=<hiero>S-HqA-q:n:nw-D40</hiero>}}{{pb}}Second Horus name:{{ubl|{{transliteration|egy|ḥḳꜣ-ḳnj tkn-ḫꜣswt}}|{{transliteration|egy|Heqaqeni tekenkhasut}}|The brave ruler who has attacked foreign lands}} {{Infobox pharaoh/Serekh |Horus=<hiero>HqA-q:n:nw:D40-t:k:n:D54-N25:N25:N25</hiero>}}{{pb}}Third Horus name:{{ubl|{{transliteration|egy|ḥḳꜣ ḥḳꜣw nw tꜣ (r) ḏr-f}}|{{transliteration|egy|Heqa heqau nu ta (er) djeref}}|The ruler of the rulers of the entire land}} {{Infobox pharaoh/Serekh |Horus=<hiero>HqA-q-HqA-HqA-q-N33-nw-N33-N17:N34-r:f</hiero>}}Fourth Horus name:{{ubl|{{transliteration|egy|ṯmꜣ-ꜥ}}|{{transliteration|egy|Tjema'a}}|The sturdy-armed one}} {{Infobox pharaoh/Serekh |Horus=<hiero>T:mA-a</hiero>}} |nebty={{ubl|{{transliteration|egy|mꜣj wr-pḥty jṯ ḏww tꜣw ḫꜣswt}}|{{transliteration|egy|Mai werpehty itj dju tau khasut}}|The lion, great of might, who takes possession of mountains, lands, and deserts}} |nebty_hiero=<hiero>E23-wr:r-F9:F9-V15-N25:N25:N33-N17:N17:N33-N25:N25:N33</hiero> |golden={{ubl|{{transliteration|egy|kꜣ (nḫt) ḫwj bꜣḳ(t) ḥḳꜣ wꜣḏ(-wr) šnw n jtn}}|{{transliteration|egy|Ka (nakht) khui baq(et) heqa wadj(wer) shenu en Aten}}|The (strong) bull who protects Egypt, the ruler of the sea and of what the sun encircles}} |golden_hiero=<hiero>E1:n-i-w*x-D40-q:t-b-</hiero>{{pb}}<hiero>D10-HqA-M14-N35A-V9:Z1-i-t:n:HASH</hiero> |prenomen={{ubl|{{transliteration|egy|stp.n-rꜥ mrj-jmn}}|{{transliteration|egy|Setepenre meryamun}}|Chosen by Ra, beloved by Amun{{pb}}{{Infobox pharaoh/Prenomen |Prenomen=<hiero>C2\-C12-stp:n:N36</hiero>}}{{pb}}{{Infobox pharaoh/Prenomen |Prenomen=<hiero>mr\-C12\-C2-stp:n</hiero>}}}}}}
32+
}}
33+
| succession4 = [[King of Persia]]
34+
| reign4 = 330–323 BC
35+
| predecessor4 = Darius III
36+
| successor4 = {{hlist|
37+
| Alexander IV
38+
| Philip III
39+
}}
40+
| full name =
41+
| spouse = {{hlist|
42+
| [[Roxana]]
43+
| [[Stateira (wife of Alexander the Great)|Stateira]]
44+
| [[Parysatis II|Parysatis]]
45+
}}
46+
| issue = {{plainlist|
47+
* [[Alexander IV of Macedon|Alexander IV]]
48+
* [[Heracles of Macedon|Heracles]]{{Cref2|a}}
49+
}}
50+
| native_lang1 = [[Ancient Greek|Greek]]
51+
| native_lang1_name1 = {{lang|grc|Ἀλέξανδρος}}{{Cref2|b}}
52+
| house = [[Argead dynasty|Argead]]
53+
| house-type = Dynasty
54+
| father = [[Philip II of Macedon]]
55+
| mother = [[Olympias|Olympias of Epirus]]
56+
| birth_date = 20 or 21 July 356 BC
57+
| birth_place = [[Pella]], [[Macedonia (ancient kingdom)|Macedon]]
58+
| death_date = 10 or 11 June 323 BC (aged 32)<!-- 32 years, 10 months and 20 days (approx.) -->
59+
| death_place = [[Babylon]], [[Mesopotamia]], Macedonian Empire
60+
| religion = [[Ancient Greek religion]]
61+
}}
62+
63+
'''Alexander III of Macedon''' ({{lang-grc|[[wikt:Ἀλέξανδρος|Ἀλέξανδρος]]|Alexandros}}; 20/21 July 356 BC – 10/11 June 323 BC), most commonly known as '''Alexander the Great''',{{Cref2|c}} was a king of the [[Ancient Greece|ancient Greek]] kingdom of [[Macedonia (ancient kingdom)|Macedon]].{{Cref2|d}} He succeeded his father [[Philip II of Macedon|Philip II]] to the throne in 336 BC at the age of 20 and spent most of his ruling years conducting a lengthy [[military campaign]] throughout [[Western Asia]], [[Central Asia]], parts of [[South Asia]], and [[ancient Egypt|Egypt]]. By the age of 30, he had created one of the [[List of largest empires|largest empires]] in history, stretching from [[History of Greece|Greece]] to northwestern [[Historical India|India]].<ref>Bloom, Jonathan M.; Blair, Sheila S. (2009) ''The Grove Encyclopedia of Islamic Art and Architecture: Mosul to Zirid, Volume 3''. (Oxford University Press Incorporated, 2009), 385; "[Khojand, Tajikistan]; As the easternmost outpost of the empire of Alexander the Great, the city was renamed Alexandria Eschate ("furthest Alexandria") in 329 BCE."{{pb}}Golden, Peter B. ''Central Asia in World History'' (Oxford University Press, 2011), 25;"[...] his campaigns in Central Asia brought Khwarazm, Sogdia and Bactria under Graeco-Macedonian rule. As elsewhere, Alexander founded or renamed a number of cities, such as Alexandria Eschate ("Outernmost Alexandria", near modern Khojent in Tajikistan)."</ref> He was undefeated in battle and is widely considered to be one of history's greatest and most successful military commanders.{{Sfn |Yenne|2010 | page = 159}}<ref>{{cite encyclopedia|title=Alexander the Great's Achievements|encyclopedia=Britannica|url=https://www.britannica.com/summary/Alexander-the-Greats-Achievements|access-date=19 August 2021|archive-date=2 July 2021|archive-url=https://web.archive.org/web/20210702234248/https://www.britannica.com/summary/Alexander-the-Greats-Achievements|url-status=live}} "Alexander the Great was one of the greatest military strategists and leaders in world history."</ref>
64+
65+
Until the age of 16, Alexander was tutored by [[Aristotle]]. In 335 BC, shortly after his assumption of kingship over Macedon, he [[Alexander's Balkan campaign|campaigned in the Balkans]] and reasserted control over [[Thrace]] and parts of [[Illyria]] before marching on the city of [[Thebes, Greece|Thebes]], which was [[Battle of Thebes|subsequently destroyed in battle]]. Alexander then led the [[League of Corinth]], and used his authority to launch the [[Greek nationalism#History|pan-Hellenic project]] envisaged by his father, assuming leadership over all [[Greeks]] in their conquest of [[Greater Iran|Persia]].{{sfn|Heckel|Tritle|2009|p=99}}<ref>{{cite book |last1=Burger |first1=Michael |title=The Shaping of Western Civilization: From Antiquity to the Enlightenment |date=2008 |publisher=University of Toronto Press |isbn=978-1-55111-432-3 |page=76}}</ref>
66+
67+
In 334 BC, he invaded the [[Achaemenid Empire|Achaemenid Persian Empire]] and began [[Wars of Alexander the Great#Persia|a series of campaigns]] that lasted for 10 years. Following his conquest of [[Asia Minor]], Alexander broke the power of Achaemenid Persia in a series of decisive battles, including those at [[Battle of Issus|Issus]] and [[Battle of Gaugamela|Gaugamela]]; he subsequently overthrew [[Darius III]] and conquered the Achaemenid Empire in its entirety.{{Cref2|e}} After the fall of Persia, the [[Macedonian Empire]] held a vast swath of territory between the [[Adriatic Sea]] and the [[Indus River]]. Alexander endeavored to reach the "ends of the world and the Great Outer Sea" and [[Indian campaign of Alexander the Great|invaded India]] in 326 BC, achieving an important victory over [[Porus]], an ancient Indian king of present-day [[Punjab]], at the [[Battle of the Hydaspes]]. Due to the demand of his homesick troops, he eventually turned back at the [[Beas River]] and later died in 323 BC in [[Babylon]], the city of [[Mesopotamia]] that he had planned to establish as his empire's capital. [[Death of Alexander the Great|Alexander's death]] left unexecuted an additional series of planned military and mercantile campaigns that would have begun with a Greek invasion of [[Arabian Peninsula|Arabia]]. In the years following his death, [[Wars of the Diadochi|a series of civil wars]] broke out across the Macedonian Empire, eventually leading to its disintegration at the hands of the [[Diadochi]].
68+
69+
With his death marking the start of the [[Hellenistic period]], Alexander's legacy includes the [[cultural diffusion]] and [[syncretism]] that his conquests engendered, such as [[Greco-Buddhism]] and [[Hellenistic Judaism]]. [[List of cities founded by Alexander the Great|He founded more than twenty cities]], with the most prominent being the city of [[Alexandria]] in Egypt. Alexander's settlement of [[Greek colonisation|Greek colonists]] and the resulting spread of [[Culture of Greece|Greek culture]] led to the overwhelming dominance of [[Hellenistic civilization]] and influence as far east as the [[Indian subcontinent]]. The Hellenistic period developed through the [[Roman Empire]] into modern [[Western culture]]; the [[Greek language]] became the ''[[lingua franca]]'' of the region and was the predominant language of the [[Byzantine Empire]] up until its collapse in the mid-15th century AD. Alexander became legendary as a classical hero in the mould of [[Achilles]], featuring prominently in the historical and mythical traditions of both Greek and non-Greek cultures. His military achievements and unprecedented enduring successes in battle made him the measure against which many later military leaders would compare themselves,{{cref2|f}} and his tactics remain a significant subject of study in [[Military academy|military academies]] worldwide.{{Sfn|Yenne|2010|page=viii}}
70+
71+
{{TOC limit|3}}
72+
73+
==Early life==
74+
75+
===Lineage and childhood===
76+
77+
[[File:Archaeological Site of Pella by Joy of Museums.jpg|thumb|upright=1.2|Archaeological site of [[Pella]], Greece, Alexander's birthplace]]
78+
{{Alexander the Great series}}
79+
Alexander III was born in [[Pella]], the capital of the [[Macedonia (ancient kingdom)|Kingdom of Macedon]],<ref>{{cite book |last=Green |first=Peter |title=Alexander of Macedon, 356–323 B.C.: a historical biography |url=https://books.google.com/books?id=g6Wl4AKGQkIC&pg=PA559 |page=xxxiii |year=1970 |series=Hellenistic culture and society |edition=illustrated, revised reprint |publisher=University of California Press |isbn=978-0-520-07165-0 |quote=356 – Alexander born in Pella. The exact date is not known, but probably either 20 or 26 July. |access-date=20 June 2015}}</ref> on the sixth day of the [[Ancient Greek calendars|ancient Greek month]] of [[Attic calendar|Hekatombaion]], which probably corresponds to 20 July 356 BC (although the exact date is uncertain).<ref>Plutarch, ''Life of Alexander'' 3.5: {{cite web |url=https://www.livius.org/aj-al/alexander/alexander_t32.html#7 |title=The birth of Alexander the Great |work=Livius|archive-url=https://web.archive.org/web/20150320180439/https://www.livius.org/aj-al/alexander/alexander_t32.html|archive-date=20 March 2015|url-status = dead |access-date=16 December 2011 |quote=Alexander was born the sixth of [[Attic calendar|Hekatombaion]].}}</ref><ref>{{cite book |author=David George Hogarth |date=1897 |title=Philip and Alexander of Macedon : two essays in biography |url=https://archive.org/details/cu31924028251217/page/n321/mode/2up?view=theater |location=New York |publisher=Charles Scribner's Sons |pages=286–287 |access-date=9 November 2021}}</ref> He was the son of the erstwhile king of Macedon, [[Philip II of Macedon|Philip II]], and his fourth wife, [[Olympias]] (daughter of [[Neoptolemus I of Epirus|Neoptolemus I]], king of [[Epirus (ancient state)|Epirus]]).<ref>{{harvnb|McCarty|2004|p=10}}, {{harvnb|Renault|2001|p=28}}, {{harvnb|Durant|1966|p=538}}</ref>{{Cref2|g}} Although Philip had seven or eight wives, Olympias was his principal wife for some time, likely because she gave birth to Alexander.{{sfn|Roisman|Worthington|2010|p=171}}
80+
81+
Several legends surround Alexander's birth and childhood.{{sfn|Roisman|Worthington|2010|p=188}} According to the [[Ancient Greeks|ancient Greek]] biographer [[Plutarch]], on the eve of the consummation of her marriage to Philip, Olympias dreamed that her womb was struck by a thunderbolt that caused a flame to spread "far and wide" before dying away. Sometime after the wedding, Philip is said to have seen himself, in a dream, securing his wife's womb with a [[Seal (emblem)|seal]] engraved with a lion's image.<ref name="PA2" /> Plutarch offered a variety of interpretations for these dreams: that Olympias was pregnant before her marriage, indicated by the sealing of her womb; or that Alexander's father was [[Zeus]]. Ancient commentators were divided about whether the ambitious Olympias promulgated the story of Alexander's divine parentage, variously claiming that she had told Alexander, or that she dismissed the suggestion as impious.<ref name="PA2" />
82+
"""

0 commit comments

Comments
 (0)