Skip to content

Commit 8b97762

Browse files
authored
Merge pull request #201 from clerk/jigarp/user-4157-fix-api-key-request-state-mapping
fix: Correctly return either org_id or user_id when using api_key token type
2 parents 215e4eb + 1fcba19 commit 8b97762

File tree

2 files changed

+59
-2
lines changed

2 files changed

+59
-2
lines changed

src/clerk_backend_api/security/types.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,9 +279,17 @@ def to_auth(self) -> AuthObject:
279279
name=self.payload.get('name'),
280280
scopes=self.payload.get('scopes'))
281281
if token_type == TokenType.API_KEY:
282+
subject = self.payload.get('subject')
283+
user_id = None
284+
org_id = None
285+
if subject:
286+
if subject.startswith('user_'):
287+
user_id = subject
288+
elif subject.startswith('org_'):
289+
org_id = subject
282290
return APIKeyMachineAuthObject(id=self.payload.get('id'),
283-
user_id=self.payload.get('subject'),
284-
org_id=self.payload.get('org_id'),
291+
user_id=user_id,
292+
org_id=org_id,
285293
name=self.payload.get('name'),
286294
scopes=self.payload.get('scopes'),
287295
claims=self.payload.get('claims'))

tests/test_authenticate_request.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,55 @@ def test_api_key_machine_auth_token(mock_verify_token):
369369
assert api_key_machine_auth_object.claims == {"foo": "bar"}
370370

371371

372+
@patch("clerk_backend_api.security.authenticaterequest.verify_token", autospec=True)
373+
def test_api_key_machine_auth_token_with_org_subject(mock_verify_token):
374+
"""Test that API key with org_ prefixed subject maps to org_id, not user_id."""
375+
mock_verify_token.return_value = {
376+
"object": "api_key",
377+
"id": "ak_3beecc9c60adb5f9b850e91a8ee1e992",
378+
"type": "api_key",
379+
"subject": "org_2xhFjEI5X2qWRvtV13BzSj8H6Dk",
380+
"name": "ORG_API_KEY",
381+
"description": "This is an org-level API Key",
382+
"claims": {
383+
"foo": "bar"
384+
},
385+
"scopes": [
386+
"read",
387+
"write"
388+
],
389+
"revoked": False,
390+
"revocation_reason": "Revoked by user",
391+
"expired": False,
392+
"expiration": 1716883200,
393+
"created_by": "user_2xhFjEI5X2qWRvtV13BzSj8H6Dk",
394+
"last_used_at": 1716883200,
395+
"created_at": 1716883200,
396+
"updated_at": 1716883200
397+
}
398+
399+
request = MockRequest(headers=make_headers(auth_token="ak_0ef5a7a33d87ed87ee7954c845d80450"))
400+
opts = AuthenticateRequestOptions(
401+
secret_key=None,
402+
jwt_key=None,
403+
audience="test-audience",
404+
authorized_parties=["https://example.com"],
405+
clock_skew_in_ms=5000,
406+
accepts_token=["api_key"])
407+
state = authenticate_request(request, opts)
408+
assert state.is_authenticated
409+
assert state.token == "ak_0ef5a7a33d87ed87ee7954c845d80450"
410+
api_key_machine_auth_object = state.to_auth()
411+
412+
assert api_key_machine_auth_object is not None
413+
assert api_key_machine_auth_object.token_type.value == "api_key"
414+
assert api_key_machine_auth_object.id == "ak_3beecc9c60adb5f9b850e91a8ee1e992"
415+
assert api_key_machine_auth_object.user_id is None
416+
assert api_key_machine_auth_object.org_id == "org_2xhFjEI5X2qWRvtV13BzSj8H6Dk"
417+
assert api_key_machine_auth_object.name == "ORG_API_KEY"
418+
assert api_key_machine_auth_object.claims == {"foo": "bar"}
419+
420+
372421
@patch("clerk_backend_api.security.authenticaterequest.verify_token", autospec=True)
373422
def test_m2m_machine_auth_token(mock_verify_token):
374423
mock_verify_token.return_value = {

0 commit comments

Comments
 (0)