Skip to content

fix: add scopes field to API key schemas in OpenAPI docs#6733

Open
WiZzArD07 wants to merge 2 commits intoBasedHardware:mainfrom
WiZzArD07:fix-api-scopes-doc
Open

fix: add scopes field to API key schemas in OpenAPI docs#6733
WiZzArD07 wants to merge 2 commits intoBasedHardware:mainfrom
WiZzArD07:fix-api-scopes-doc

Conversation

@WiZzArD07
Copy link
Copy Markdown

What I changed

  • Added scopes field to ApiKey, ApiKeyCreated, and CreateApiKey schemas

Why

The implementation supports API key scopes, but this field was missing from the OpenAPI documentation.

Related Issue

Fixes #6698

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 17, 2026

Greptile Summary

This PR adds the missing scopes field to the ApiKey, ApiKeyCreated, and CreateApiKey OpenAPI schemas, correctly surfacing an existing backend feature. The implementation is accurate and the CreateApiKey description ("Defaults to read-only if not provided") matches the database layer.

  • ApiKey and ApiKeyCreated response schemas declare scopes as type: \"array\", but get_dev_keys_for_user sets scopes = None for backward-compatible legacy keys, meaning the API can return \"scopes\": null. This should be type: [\"array\", \"null\"] to match how last_used_at is already declared in the same schemas.
  • Minor: inconsistent leading whitespace on the scopes block in ApiKeyCreated and CreateApiKey, and the CreateApiKey.scopes description omits the list of valid scope strings.

Confidence Score: 3/5

The response schemas declare scopes as non-nullable, but the API can return null for legacy keys — fix the type before merging to avoid breaking strict consumers.

Two P1 findings: ApiKey and ApiKeyCreated both declare scopes as always-array, contradicting the backend behavior where old keys have scopes: null. This is a documentation contract mismatch that will mislead consumers who generate client code from the spec.

docs/api-reference/openapi.json — lines 1044-1048 (ApiKey.scopes) and 1061-1065 (ApiKeyCreated.scopes)

Important Files Changed

Filename Overview
docs/api-reference/openapi.json Adds scopes field to ApiKey, ApiKeyCreated, and CreateApiKey schemas; however ApiKey and ApiKeyCreated are missing nullable (type: ["array", "null"]) to reflect that legacy keys can return null for this field, and there is minor inconsistent indentation in the two new blocks.

Sequence Diagram

sequenceDiagram
    participant Client
    participant API as Developer API
    participant DB as Firestore

    Client->>API: POST /v1/dev/keys {name, scopes?}
    API->>API: validate_scopes(scopes)
    Note over API: If scopes=null, defaults to READ_ONLY_SCOPES
    API->>DB: create_dev_key(uid, name, scopes)
    DB-->>API: DevApiKeyCreated {id, key, scopes}
    API-->>Client: 200 {id, key, scopes: ["conversations:read", ...]}

    Client->>API: GET /v1/dev/keys
    API->>DB: get_dev_keys_for_user(uid)
    Note over DB: Legacy keys: scopes field absent, set to null
    DB-->>API: List[DevApiKey] with scopes null or array
    API-->>Client: 200 [{scopes: null}, {scopes: ["memories:read"]}]
    Note over Client: Spec says array, but can be null for legacy keys
Loading

Reviews (1): Last reviewed commit: "fix: add scopes field to API key schemas..." | Re-trigger Greptile

Comment on lines +1044 to +1048
"scopes": {
"type": "array",
"items": { "type": "string" },
"description": "Permission scopes assigned to the API key."
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 scopes should be marked nullable in response schemas

DevApiKey.scopes is typed Optional[List[str]] = None in the backend model, and get_dev_keys_for_user explicitly sets it to None for backward-compatible keys that predate the scopes feature. The GET endpoint can therefore return "scopes": null for existing keys. The current schema (type: "array") implies the field is always an array, which will mislead consumers who rely on the spec. To match last_used_at's pattern, both ApiKey.scopes and ApiKeyCreated.scopes should use type: ["array", "null"].

Suggested change
"scopes": {
"type": "array",
"items": { "type": "string" },
"description": "Permission scopes assigned to the API key."
}
"scopes": {
"type": ["array", "null"],
"items": { "type": "string" },
"description": "Permission scopes assigned to the API key. Null for legacy keys (treated as read-only)."
}

Comment thread docs/api-reference/openapi.json Outdated
Comment on lines +1061 to +1065
"scopes": {
"type": "array",
"items": { "type": "string" },
"description": "Permission scopes assigned to the API key."
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 ApiKeyCreated.scopes also needs nullable type

Same issue as ApiKey.scopesDevApiKeyCreated extends DevApiKey and inherits scopes: Optional[List[str]] = None. Old keys retrieved after creation can still surface a null value here.

Suggested change
"scopes": {
"type": "array",
"items": { "type": "string" },
"description": "Permission scopes assigned to the API key."
}
"scopes": {
"type": ["array", "null"],
"items": { "type": "string" },
"description": "Permission scopes assigned to the API key. Null for legacy keys (treated as read-only)."
}

Comment thread docs/api-reference/openapi.json Outdated
Comment on lines +1074 to +1078
"scopes": {
"type": "array",
"items": { "type": "string" },
"description": "Optional scopes to assign. Defaults to read-only if not provided."
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Inconsistent indentation and missing valid scope values

The scopes block in ApiKeyCreated and CreateApiKey has an extra leading space (11 spaces vs 10 for all other properties) that is inconsistent with the rest of the file. This is purely cosmetic but worth fixing for consistency.

Additionally, the description "Optional scopes to assign. Defaults to read-only if not provided." doesn't mention what valid values look like. The developer.py router docstring lists all 8 available scopes (conversations:read/write, memories:read/write, action_items:read/write, goals:read/write). Adding an enum or at least listing them in the description would make this self-contained.

Suggested change
"scopes": {
"type": "array",
"items": { "type": "string" },
"description": "Optional scopes to assign. Defaults to read-only if not provided."
}
"scopes": {
"type": "array",
"items": {
"type": "string",
"enum": [
"conversations:read", "conversations:write",
"memories:read", "memories:write",
"action_items:read", "action_items:write",
"goals:read", "goals:write"
]
},
"description": "Optional scopes to assign. Defaults to read-only (conversations:read, memories:read, action_items:read, goals:read) if not provided."
}

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Copy link
Copy Markdown
Author

@WiZzArD07 WiZzArD07 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the schemas to address review comments. Let me know if anything else needs adjustment .

@WiZzArD07
Copy link
Copy Markdown
Author

Hi! I've addressed the review feedback and updated the schemas (nullable scopes, enum, formatting).

Would appreciate a review when you have time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Docs] Docs/code alignment follow-up for developer API and runbooks

1 participant