Skip to content

Commit f71501e

Browse files
shaharglclaude
andauthored
fix: prevent deleted API keys from being used for authentication (#5277)
Co-authored-by: Claude <[email protected]>
1 parent a2a2519 commit f71501e

File tree

3 files changed

+57
-2
lines changed

3 files changed

+57
-2
lines changed

keep/api/core/db.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2027,10 +2027,12 @@ def get_alerts_by_status(
20272027
return session.exec(query).all()
20282028

20292029

2030-
def get_api_key(api_key: str) -> TenantApiKey:
2030+
def get_api_key(api_key: str, include_deleted: bool = False) -> TenantApiKey:
20312031
with Session(engine) as session:
20322032
api_key_hashed = hashlib.sha256(api_key.encode()).hexdigest()
20332033
statement = select(TenantApiKey).where(TenantApiKey.key_hash == api_key_hashed)
2034+
if not include_deleted:
2035+
statement = statement.where(TenantApiKey.is_deleted != True)
20342036
tenant_api_key = session.exec(statement).first()
20352037
return tenant_api_key
20362038

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "keep"
3-
version = "0.47.3"
3+
version = "0.47.4"
44
description = "Alerting. for developers, by developers."
55
authors = ["Keep Alerting LTD"]
66
packages = [{include = "keep"}]

tests/test_auth.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,3 +378,56 @@ def test_oauth_proxy2(db_session, client, test_app):
378378
json={"email": "shahar", "role": "admin"},
379379
)
380380
assert response.status_code == 403
381+
382+
383+
@pytest.mark.parametrize(
384+
"test_app", ["SINGLE_TENANT", "MULTI_TENANT", "NO_AUTH"], indirect=True
385+
)
386+
def test_deleted_api_key_authentication(db_session, client, test_app):
387+
"""Tests that deleted API keys cannot be used for authentication"""
388+
import hashlib
389+
from keep.api.core.dependencies import SINGLE_TENANT_UUID
390+
from keep.api.models.db.tenant import TenantApiKey
391+
from keep.api.core.db import get_api_key
392+
393+
auth_type = os.getenv("AUTH_TYPE")
394+
valid_api_key = "test_deleted_key"
395+
396+
# Create API key in database directly
397+
hash_api_key = hashlib.sha256(valid_api_key.encode()).hexdigest()
398+
api_key_entry = TenantApiKey(
399+
tenant_id=SINGLE_TENANT_UUID,
400+
reference_id="test_deleted",
401+
key_hash=hash_api_key,
402+
created_by="[email protected]",
403+
role="admin",
404+
is_deleted=False
405+
)
406+
db_session.add(api_key_entry)
407+
db_session.commit()
408+
409+
# Test that non-deleted API key works
410+
response = client.get("/providers", headers={"x-api-key": valid_api_key})
411+
assert response.status_code == 200
412+
413+
# Test get_api_key function directly - should find non-deleted key
414+
found_key = get_api_key(valid_api_key)
415+
assert found_key is not None
416+
assert found_key.is_deleted == False
417+
418+
# Mark API key as deleted
419+
api_key_entry.is_deleted = True
420+
db_session.commit()
421+
422+
# Test that deleted API key is rejected
423+
response = client.get("/providers", headers={"x-api-key": valid_api_key})
424+
assert response.status_code == 401 if auth_type != "NO_AUTH" else 200
425+
426+
# Test get_api_key function directly - should NOT find deleted key by default
427+
found_key = get_api_key(valid_api_key)
428+
assert found_key is None
429+
430+
# Test get_api_key function with include_deleted=True - should find deleted key
431+
found_key = get_api_key(valid_api_key, include_deleted=True)
432+
assert found_key is not None
433+
assert found_key.is_deleted == True

0 commit comments

Comments
 (0)