Skip to content

Conversation

@romartin
Copy link
Contributor

@romartin romartin commented Nov 30, 2025

Description

Added a basic API Key authentication mechanism, really similar to the noop_with_token, but it checks the Bearer token value is equal to a given API Key, from configuration parameters.

See https://issues.redhat.com/browse/AAP-59476

It allows production deployment, although it is a basic mechanism, so no expiration and revocation, and token is not self-contained, no information on payload.

Type of change

  • Refactor
  • New feature
  • Bug fix
  • CVE fix
  • Optimization
  • Documentation Update
  • Configuration Update
  • Bump-up service version
  • Bump-up dependent library
  • Bump-up library or tool used for development (does not change the final image)
  • CI configuration change
  • Konflux configuration change
  • Unit tests improvement
  • Integration tests improvement
  • End to end tests improvement

Tools used to create PR

None

Related Tickets & Documents

Checklist before requesting a review

  • I have performed a self-review of my code.
  • PR has passed all pre-merge test jobs.
  • If it is a core feature, I have added thorough tests.

Testing

  • Please provide detailed steps to perform tests related to this code change.

1.- In lightspeed-stack.yaml, change the authentication section as:

authentication:
  module: "api-key-token"
  api_key_config:
    api_key: "some-api-key"

2.- Run lightspeed-stack and use Baerer token to authenticate

3.- Otherwise expect an HTTP 401

  • How were the fix/results from this change verified? Please provide relevant screenshots or results.
    Tested using Postman.

Summary by CodeRabbit

  • New Features

    • API Key Token authentication option is now available for Bearer-token based requests.
  • Documentation

    • Public configuration schema and docs updated to include an API key configuration option and richer descriptions across multiple configuration sections.
  • Examples

    • Added an example configuration demonstrating API Key Token authentication.
  • Tests

    • Added unit tests covering successful and failure API Key authentication scenarios.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 30, 2025

Walkthrough

Adds an API Key Token authentication module ("api-key-token") that validates a Bearer token from the Authorization header against a configured API key, wires the module into auth and authorization flows, adds config/schema/docs/examples, and includes unit tests. (28 words)

Changes

Cohort / File(s) Summary
Core authentication
src/authentication/api_key_token.py
New APIKeyTokenAuthDependency: extracts Bearer token from Authorization header, compares to configured api_key using secrets.compare_digest, returns auth tuple on success or raises HTTP 401 on failure.
Factory & exports
src/authentication/__init__.py
Imports api_key_token and returns APIKeyTokenAuthDependency from get_auth_dependency when AUTH_MOD_APIKEY_TOKEN is selected.
Constants
src/constants.py
Added AUTH_MOD_APIKEY_TOKEN = "api-key-token" and included it in SUPPORTED_AUTHENTICATION_MODULES.
Configuration models
src/models/config.py
Added APIKeyTokenConfiguration (api_key: SecretStr), added api_key_config: Optional[APIKeyTokenConfiguration] to AuthenticationConfiguration, added api_key_configuration accessor and validation for api-key-token in check_authentication_model.
Authorization mapping
src/authorization/middleware.py
Registered AUTH_MOD_APIKEY_TOKEN to resolve to NoopRolesResolver / NoopAccessResolver in resolver selection.
Documentation & schemas
docs/auth.md, docs/openapi.json, docs/output.md
Added docs and OpenAPI schema for APIKeyTokenConfiguration and api_key_config; expanded various configuration descriptions and metadata.
Examples
examples/lightspeed-stack-api-key-auth.yaml
New example YAML demonstrating api-key-token configuration with api_key.
READMEs
src/authentication/README.md, src/utils/README.md, tests/unit/authentication/README.md, tests/unit/utils/README.md
Added README entries describing the new auth dependency, responses util, and related tests/docs.
Tests
tests/unit/authentication/test_api_key_token.py, tests/unit/models/config/test_dump_configuration.py, tests/unit/models/config/test_authentication_configuration.py
New unit tests covering success/failure scenarios for APIKeyTokenAuthDependency; updated dump/config tests to include api_key_config expectations and validate config validation behavior.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant FastAPI
    participant AuthDep as APIKeyTokenAuthDependency
    participant Config as AuthenticationConfiguration
    participant AuthZ as AuthorizationResolvers

    Client->>FastAPI: HTTP request (Authorization: Bearer <token>)
    FastAPI->>AuthDep: call dependency(request)
    AuthDep->>FastAPI: extract Authorization header/token
    AuthDep->>Config: read api_key_config.api_key
    alt token == config.api_key
        AuthDep-->>FastAPI: return (user_id, username, skip_userid_check, token)
        FastAPI->>AuthZ: resolve roles/access (noop)
        FastAPI-->>Client: proceed to endpoint (200)
    else invalid or missing
        AuthDep-->>FastAPI: raise HTTP 401 (error detail)
        FastAPI-->>Client: 401 Unauthorized
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas needing extra attention:
    • Validation logic and error messages in src/models/config.py.
    • Header parsing, constant-time comparison, and HTTP exception details in src/authentication/api_key_token.py.
    • Correct wiring in src/authentication/__init__.py and src/authorization/middleware.py.
    • Test coverage: tests/unit/authentication/test_api_key_token.py and updated serialization expectations.

Possibly related PRs

Suggested labels

ok-to-test

Suggested reviewers

  • tisnik

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: adding a new API Key Bearer token authentication module (api-key-token), which is the primary purpose of this PR.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci
Copy link

openshift-ci bot commented Nov 30, 2025

Hi @romartin. Thanks for your PR.

I'm waiting for a github.com member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (7)
src/authentication/api_key_token.py (2)

27-33: Consider removing unused virtual_path parameter.

The virtual_path parameter is stored in self.virtual_path but never used within this class. Based on the pattern from other authentication modules and the relevant code snippets, it appears this parameter may have been copied from another authentication implementation but isn't needed for API key validation.

If virtual_path is not needed for future enhancements, consider removing it:

     def __init__(
-        self, config: APIKeyTokenConfiguration, virtual_path: str = DEFAULT_VIRTUAL_PATH
+        self, config: APIKeyTokenConfiguration
     ) -> None:
-        """Initialize the required allowed paths for authorization checks."""
-        self.virtual_path: str = virtual_path
+        """Initialize the API key authentication dependency."""
         self.config: APIKeyTokenConfiguration = config
         self.skip_userid_check = True

44-52: Remove redundant None check for user_token.

The condition user_token is None is redundant because extract_user_token (from authentication.utils) never returns None — it either returns a string or raises an HTTPException. The None check adds unnecessary complexity.

Apply this diff:

         # try to extract user token from request
         user_token = extract_user_token(request.headers)
 
         # API Key validation.
-        if user_token is None or user_token != self.config.api_key:
+        if user_token != self.config.api_key:
             raise HTTPException(
                 status_code=status.HTTP_401_UNAUTHORIZED,
                 detail="Invalid API Key",
             )
src/models/config.py (1)

741-749: Simplify redundant None check for api_key.

Line 746 checks if self.api_key_config.api_key is None, but according to the APIKeyTokenConfiguration model definition (line 705), api_key has a default value of constants.DEFAULT_API_KEY. With Pydantic, this field can never be None unless explicitly set to None, which would require Optional[str].

Consider removing the redundant check:

         if self.module == constants.AUTH_MOD_APIKEY_TOKEN:
             if self.api_key_config is None:
                 raise ValueError(
                     "API_KEY configuration section must be specified when using API_KEY token authentication"
                 )
-            if self.api_key_config.api_key is None:
-                raise ValueError(
-                    "api_key parameter must be specified when using API_KEY token authentication"
-                )

Alternatively, if you want to prevent users from using the default value in production, you could add a more specific validation that checks if the key equals constants.DEFAULT_API_KEY.

docs/openapi.json (3)

4530-4539: api_key_config wiring looks fine; document/validate module value.

The new anyOf is good. Please either:

  • document allowed values for authentication.module including "api-key-token", or
  • add a non-breaking enum that includes it.

If enums are used elsewhere, ensure "api-key-token" matches the implementation string exactly to avoid drift.


4361-4362: Add a Bearer security scheme to components.

Define a reusable bearer scheme so UIs show the expected “Authorization: Bearer ” flow. You can keep security application per‑endpoint or conditional at runtime.

   "components": {
-    "schemas": {
+    "securitySchemes": {
+      "BearerAuth": {
+        "type": "http",
+        "scheme": "bearer",
+        "bearerFormat": "API Key"
+      }
+    },
+    "schemas": {

7566-7640: Add a 401 example for invalid API key (Bearer mismatch).

New module returns 401 when the Bearer token ≠ configured api_key. Add an example to make this explicit.

       "UnauthorizedResponse": {
         ...
         "examples": [
           {
             "label": "missing header",
             "detail": { "cause": "No Authorization header found", "response": "Missing or invalid credentials provided by client" }
           },
           {
             "label": "missing token",
             "detail": { "cause": "No token found in Authorization header", "response": "Missing or invalid credentials provided by client" }
           },
+          {
+            "label": "invalid api key",
+            "detail": {
+              "cause": "Bearer token does not match configured API key",
+              "response": "Missing or invalid credentials provided by client"
+            }
+          },
           {
             "label": "expired token",
             "detail": { "cause": "Token has expired", "response": "Missing or invalid credentials provided by client" }
           },
docs/output.md (1)

4009-4026: Minor markdown formatting issues flagged by linting tools.

Static analysis identified several markdown formatting issues in this file:

  • List indentation inconsistencies at lines 4015-4017, 4517-4519, 4965-4967 (MD007)
  • Bare URL at line 4756 without link formatting (MD034)

Since this file is auto-generated documentation, these are low priority. However, if the source generation tool can be configured to emit proper markdown, it would improve compliance with linting standards.

Also applies to: 4020-4046, 4036-4048

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0a130b0 and d864f0b.

📒 Files selected for processing (14)
  • docs/auth.md (1 hunks)
  • docs/openapi.json (27 hunks)
  • docs/output.md (14 hunks)
  • examples/lightspeed-stack-api-key-auth.yaml (1 hunks)
  • src/authentication/README.md (1 hunks)
  • src/authentication/__init__.py (2 hunks)
  • src/authentication/api_key_token.py (1 hunks)
  • src/authorization/middleware.py (1 hunks)
  • src/constants.py (2 hunks)
  • src/models/config.py (4 hunks)
  • src/utils/README.md (1 hunks)
  • tests/unit/authentication/README.md (1 hunks)
  • tests/unit/authentication/test_api_key_token.py (1 hunks)
  • tests/unit/utils/README.md (1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
src/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/**/*.py: Use absolute imports for internal modules in LCS project (e.g., from auth import get_auth_dependency)
All modules must start with descriptive docstrings explaining their purpose
Use logger = logging.getLogger(__name__) pattern for module logging
All functions must include complete type annotations for parameters and return types, using modern syntax (str | int) and Optional[Type] or Type | None
All functions must have docstrings with brief descriptions following Google Python docstring conventions
Function names must use snake_case with descriptive, action-oriented names (get_, validate_, check_)
Avoid in-place parameter modification anti-patterns; return new data structures instead of modifying input parameters
Use async def for I/O operations and external API calls
All classes must include descriptive docstrings explaining their purpose following Google Python docstring conventions
Class names must use PascalCase with descriptive names and standard suffixes: Configuration for config classes, Error/Exception for exceptions, Resolver for strategy patterns, Interface for abstract base classes
Abstract classes must use ABC with @abstractmethod decorators
Include complete type annotations for all class attributes in Python classes
Use import logging and module logger pattern with standard log levels: debug, info, warning, error

Files:

  • src/models/config.py
  • src/authentication/__init__.py
  • src/constants.py
  • src/authentication/api_key_token.py
  • src/authorization/middleware.py
src/models/config.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/models/config.py: All configuration must use Pydantic models extending ConfigurationBase with extra="forbid" to reject unknown fields
Use type hints Optional[FilePath], PositiveInt, SecretStr for Pydantic configuration models

Files:

  • src/models/config.py
src/models/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/models/**/*.py: Use @field_validator and @model_validator for custom validation in Pydantic models
Pydantic configuration classes must extend ConfigurationBase; data models must extend BaseModel

Files:

  • src/models/config.py
tests/{unit,integration}/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

tests/{unit,integration}/**/*.py: Use pytest for all unit and integration tests; do not use unittest framework
Unit tests must achieve 60% code coverage; integration tests must achieve 10% coverage

Files:

  • tests/unit/authentication/test_api_key_token.py
tests/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Use pytest-mock with AsyncMock objects for mocking in tests

Files:

  • tests/unit/authentication/test_api_key_token.py
src/**/__init__.py

📄 CodeRabbit inference engine (CLAUDE.md)

Package __init__.py files must contain brief package descriptions

Files:

  • src/authentication/__init__.py
src/**/constants.py

📄 CodeRabbit inference engine (CLAUDE.md)

Define shared constants in central constants.py file with descriptive comments

Files:

  • src/constants.py
🧠 Learnings (1)
📚 Learning: 2025-09-02T11:09:40.404Z
Learnt from: radofuchs
Repo: lightspeed-core/lightspeed-stack PR: 485
File: tests/e2e/features/environment.py:87-95
Timestamp: 2025-09-02T11:09:40.404Z
Learning: In the lightspeed-stack e2e tests, noop authentication tests use the default lightspeed-stack.yaml configuration, while noop-with-token tests use the Authorized tag to trigger a config swap to the specialized noop-with-token configuration file.

Applied to files:

  • tests/unit/authentication/test_api_key_token.py
  • docs/auth.md
  • examples/lightspeed-stack-api-key-auth.yaml
  • src/authorization/middleware.py
🧬 Code graph analysis (3)
tests/unit/authentication/test_api_key_token.py (2)
src/authentication/api_key_token.py (1)
  • APIKeyTokenAuthDependency (23-54)
src/models/config.py (2)
  • config (279-285)
  • APIKeyTokenConfiguration (702-705)
src/authentication/__init__.py (3)
src/authentication/api_key_token.py (1)
  • APIKeyTokenAuthDependency (23-54)
src/configuration.py (2)
  • configuration (73-77)
  • authentication_configuration (108-113)
src/models/config.py (1)
  • api_key_configuration (776-784)
src/authentication/api_key_token.py (4)
src/authentication/interface.py (1)
  • AuthInterface (34-39)
src/authentication/utils.py (1)
  • extract_user_token (8-30)
src/log.py (1)
  • get_logger (7-13)
src/models/config.py (2)
  • config (279-285)
  • APIKeyTokenConfiguration (702-705)
🪛 LanguageTool
docs/output.md

[style] ~4041-~4041: Consider using “inaccessible” to avoid wordiness.
Context: ...figured in the llama-stack run.yaml are not accessible to lightspeed-core agents. | | authenti...

(NOT_ABLE_PREMIUM)


[style] ~4539-~4539: Consider using “inaccessible” to avoid wordiness.
Context: ...figured in the llama-stack run.yaml are not accessible to lightspeed-core agents. Useful reso...

(NOT_ABLE_PREMIUM)


[style] ~4599-~4599: It’s more common nowadays to write this noun as one word.
Context: ...connect to | | user | string | Database user name used to authenticate | | password | str...

(RECOMMENDED_COMPOUNDS)


[style] ~4769-~4769: ‘on a daily basis’ might be wordy. Consider a shorter alternative.
Context: ...ific value periodically (for example on a daily basis), set quota_increase. | Field | T...

(EN_WORDINESS_PREMIUM_ON_A_DAILY_BASIS)


[grammar] ~4775-~4775: Use a hyphen to join words.
Context: ...luster_limiter | | name | string | Human readable quota limiter name | | initial_...

(QB_NEW_EN_HYPHEN)


[grammar] ~4778-~4778: Use a hyphen to join words.
Context: ...iod | string | Period specified in human readable form | ## QuotaSchedulerConfi...

(QB_NEW_EN_HYPHEN)

🪛 markdownlint-cli2 (0.18.1)
docs/output.md

4015-4015: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


4016-4016: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


4017-4017: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


4517-4517: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


4518-4518: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


4519-4519: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


4756-4756: Bare URL used

(MD034, no-bare-urls)


4965-4965: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


4966-4966: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


4967-4967: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: e2e_tests (ci)
  • GitHub Check: e2e_tests (azure)
🔇 Additional comments (9)
src/authorization/middleware.py (1)

36-45: LGTM! Correct integration with authorization system.

The API key token authentication module is correctly mapped to NoopRolesResolver and NoopAccessResolver, consistent with the other noop-like authentication modules.

docs/auth.md (1)

145-160: LGTM! Clear and consistent documentation.

The API Key Token authentication documentation is well-structured and follows the same format as other authentication modules. The configuration example and behavior description are clear.

tests/unit/authentication/test_api_key_token.py (1)

19-122: LGTM: Comprehensive test coverage.

The test suite provides excellent coverage for the API key authentication flow, including:

  • Successful authentication with valid Bearer token
  • Missing Authorization header scenario
  • Invalid Bearer scheme handling
  • Invalid API key validation
src/models/config.py (2)

702-705: LGTM: Configuration class follows Pydantic patterns.

The APIKeyTokenConfiguration class correctly extends ConfigurationBase and uses the default API key from constants, consistent with the codebase's configuration patterns.


775-784: LGTM: Property accessor follows established patterns.

The api_key_configuration property accessor is consistent with the existing jwk_configuration and rh_identity_configuration accessors, providing appropriate validation and type safety.

src/constants.py (1)

117-117: Ensure users override the default API key in production.

The default value "some-api-key" is a weak placeholder. While this is acceptable for development and testing, ensure that documentation clearly warns users to configure a strong, unique API key in production environments. Consider adding validation or warnings when this default value is detected.

⛔ Skipped due to learnings
Learnt from: CR
Repo: lightspeed-core/lightspeed-stack PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:58:04.410Z
Learning: Applies to src/**/constants.py : Define shared constants in central `constants.py` file with descriptive comments
docs/openapi.json (1)

4696-4735: LGTM: helpful doc/title/description enrichments.

The expanded titles/descriptions (CORS, Configuration, LlamaStack, Service, TLS) improve clarity without changing signatures.

Also applies to: 4744-4787, 6047-6093, 7295-7345, 7488-7489

docs/output.md (2)

3871-3880: New APIKeyTokenConfiguration schema properly documented.

The APIKeyTokenConfiguration documentation is minimal but appropriate for this authentication module. The single api_key field is clearly documented, and the placement within the components section is consistent with other configuration types.


3943-3943: api_key_config field correctly integrated into AuthenticationConfiguration.

The optional api_key_config field is properly added to AuthenticationConfiguration alongside existing auth config options (k8s_cluster_api, jwk_config, rh_identity_config), maintaining consistency with the configuration hierarchy.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

♻️ Duplicate comments (1)
src/authentication/api_key_token.py (1)

1-7: Update the module docstring to reflect the correct return tuple.

The module docstring on line 6 still documents the return tuple incorrectly. The first element should be DEFAULT_USER_UID, not DEFAULT_USER_NAME, to match the actual return statement on line 54.

🧹 Nitpick comments (1)
examples/lightspeed-stack-api-key-auth.yaml (1)

1-15: Consider adding a comment about production API key requirements.

The example configuration is correct and well-structured. However, since this file serves as a template, consider adding a comment above the api_key field to remind users to use a strong, randomly-generated key in production environments.

Example addition:

 authentication:
   module: "api-key-token"
   api_key_config:
+    # WARNING: Use a strong, randomly-generated API key in production.
+    # Example: Use `openssl rand -base64 32` to generate a secure key.
     api_key: "some-api-key"

This helps prevent users from deploying with weak keys.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d864f0b and 595c54a.

📒 Files selected for processing (4)
  • examples/lightspeed-stack-api-key-auth.yaml (1 hunks)
  • src/authentication/__init__.py (2 hunks)
  • src/authentication/api_key_token.py (1 hunks)
  • tests/unit/authentication/test_api_key_token.py (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • tests/unit/authentication/test_api_key_token.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/authentication/init.py
🧰 Additional context used
📓 Path-based instructions (1)
src/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/**/*.py: Use absolute imports for internal modules in LCS project (e.g., from auth import get_auth_dependency)
All modules must start with descriptive docstrings explaining their purpose
Use logger = logging.getLogger(__name__) pattern for module logging
All functions must include complete type annotations for parameters and return types, using modern syntax (str | int) and Optional[Type] or Type | None
All functions must have docstrings with brief descriptions following Google Python docstring conventions
Function names must use snake_case with descriptive, action-oriented names (get_, validate_, check_)
Avoid in-place parameter modification anti-patterns; return new data structures instead of modifying input parameters
Use async def for I/O operations and external API calls
All classes must include descriptive docstrings explaining their purpose following Google Python docstring conventions
Class names must use PascalCase with descriptive names and standard suffixes: Configuration for config classes, Error/Exception for exceptions, Resolver for strategy patterns, Interface for abstract base classes
Abstract classes must use ABC with @abstractmethod decorators
Include complete type annotations for all class attributes in Python classes
Use import logging and module logger pattern with standard log levels: debug, info, warning, error

Files:

  • src/authentication/api_key_token.py
🧠 Learnings (1)
📚 Learning: 2025-09-02T11:09:40.404Z
Learnt from: radofuchs
Repo: lightspeed-core/lightspeed-stack PR: 485
File: tests/e2e/features/environment.py:87-95
Timestamp: 2025-09-02T11:09:40.404Z
Learning: In the lightspeed-stack e2e tests, noop authentication tests use the default lightspeed-stack.yaml configuration, while noop-with-token tests use the Authorized tag to trigger a config swap to the specialized noop-with-token configuration file.

Applied to files:

  • examples/lightspeed-stack-api-key-auth.yaml
🧬 Code graph analysis (1)
src/authentication/api_key_token.py (4)
src/authentication/interface.py (1)
  • AuthInterface (34-39)
src/authentication/utils.py (1)
  • extract_user_token (8-30)
src/log.py (1)
  • get_logger (7-13)
src/models/config.py (2)
  • config (279-285)
  • APIKeyTokenConfiguration (702-705)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: e2e_tests (azure)
  • GitHub Check: e2e_tests (ci)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/authentication/api_key_token.py (1)

1-7: Complete the module docstring correction.

The return tuple documentation still lists DEFAULT_USER_NAME twice instead of DEFAULT_USER_UID, DEFAULT_USER_NAME. The previous review comment was marked as addressed, but the fix was only partial (added skip_userid_check but didn't correct the first element).

Apply this diff:

 """Authentication flow for FastAPI endpoints with a provided API key.
 
 Behavior:
 - Reads a user token from request headers via `authentication.utils.extract_user_token` and verifies
 the value equals to the API Key, given from configuration parameter.
-- Returns a tuple: (DEFAULT_USER_NAME, DEFAULT_USER_NAME, skip_userid_check, user_token).
+- Returns a tuple: (DEFAULT_USER_UID, DEFAULT_USER_NAME, skip_userid_check, user_token).
 """
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 595c54a and 518ede0.

📒 Files selected for processing (3)
  • src/authentication/api_key_token.py (1 hunks)
  • src/constants.py (2 hunks)
  • src/models/config.py (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/constants.py
🧰 Additional context used
📓 Path-based instructions (3)
src/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/**/*.py: Use absolute imports for internal modules in LCS project (e.g., from auth import get_auth_dependency)
All modules must start with descriptive docstrings explaining their purpose
Use logger = logging.getLogger(__name__) pattern for module logging
All functions must include complete type annotations for parameters and return types, using modern syntax (str | int) and Optional[Type] or Type | None
All functions must have docstrings with brief descriptions following Google Python docstring conventions
Function names must use snake_case with descriptive, action-oriented names (get_, validate_, check_)
Avoid in-place parameter modification anti-patterns; return new data structures instead of modifying input parameters
Use async def for I/O operations and external API calls
All classes must include descriptive docstrings explaining their purpose following Google Python docstring conventions
Class names must use PascalCase with descriptive names and standard suffixes: Configuration for config classes, Error/Exception for exceptions, Resolver for strategy patterns, Interface for abstract base classes
Abstract classes must use ABC with @abstractmethod decorators
Include complete type annotations for all class attributes in Python classes
Use import logging and module logger pattern with standard log levels: debug, info, warning, error

Files:

  • src/models/config.py
  • src/authentication/api_key_token.py
src/models/config.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/models/config.py: All configuration must use Pydantic models extending ConfigurationBase with extra="forbid" to reject unknown fields
Use type hints Optional[FilePath], PositiveInt, SecretStr for Pydantic configuration models

Files:

  • src/models/config.py
src/models/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/models/**/*.py: Use @field_validator and @model_validator for custom validation in Pydantic models
Pydantic configuration classes must extend ConfigurationBase; data models must extend BaseModel

Files:

  • src/models/config.py
🧠 Learnings (1)
📚 Learning: 2025-11-24T16:58:04.410Z
Learnt from: CR
Repo: lightspeed-core/lightspeed-stack PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:58:04.410Z
Learning: Applies to src/**/*.py : All classes must include descriptive docstrings explaining their purpose following Google Python docstring conventions

Applied to files:

  • src/authentication/api_key_token.py
🧬 Code graph analysis (1)
src/authentication/api_key_token.py (4)
src/authentication/interface.py (1)
  • AuthInterface (34-39)
src/authentication/utils.py (1)
  • extract_user_token (8-30)
src/log.py (1)
  • get_logger (7-13)
src/models/config.py (2)
  • config (279-285)
  • APIKeyTokenConfiguration (703-713)

@are-ces
Copy link
Contributor

are-ces commented Dec 2, 2025

Please reformat the files to pass the checks (see contribution guide)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 518ede0 and fc6b447.

📒 Files selected for processing (4)
  • src/authentication/api_key_token.py (1 hunks)
  • src/models/config.py (4 hunks)
  • tests/unit/authentication/test_api_key_token.py (1 hunks)
  • tests/unit/models/config/test_dump_configuration.py (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/authentication/api_key_token.py
  • src/models/config.py
🧰 Additional context used
📓 Path-based instructions (2)
tests/{unit,integration}/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

tests/{unit,integration}/**/*.py: Use pytest for all unit and integration tests; do not use unittest framework
Unit tests must achieve 60% code coverage; integration tests must achieve 10% coverage

Files:

  • tests/unit/models/config/test_dump_configuration.py
  • tests/unit/authentication/test_api_key_token.py
tests/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Use pytest-mock with AsyncMock objects for mocking in tests

Files:

  • tests/unit/models/config/test_dump_configuration.py
  • tests/unit/authentication/test_api_key_token.py
🧠 Learnings (1)
📚 Learning: 2025-09-02T11:09:40.404Z
Learnt from: radofuchs
Repo: lightspeed-core/lightspeed-stack PR: 485
File: tests/e2e/features/environment.py:87-95
Timestamp: 2025-09-02T11:09:40.404Z
Learning: In the lightspeed-stack e2e tests, noop authentication tests use the default lightspeed-stack.yaml configuration, while noop-with-token tests use the Authorized tag to trigger a config swap to the specialized noop-with-token configuration file.

Applied to files:

  • tests/unit/authentication/test_api_key_token.py
🧬 Code graph analysis (1)
tests/unit/authentication/test_api_key_token.py (2)
src/authentication/api_key_token.py (1)
  • APIKeyTokenAuthDependency (24-67)
src/models/config.py (2)
  • config (279-285)
  • APIKeyTokenConfiguration (703-714)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: e2e_tests (azure)
  • GitHub Check: e2e_tests (ci)
🔇 Additional comments (4)
tests/unit/models/config/test_dump_configuration.py (1)

152-152: LGTM! Test expectations correctly updated for new schema field.

The addition of "api_key_config": None to the expected authentication section in all three test functions correctly reflects the new API key configuration field introduced in this PR. The placement is consistent across all tests and aligns with the schema changes.

Also applies to: 452-452, 637-637

tests/unit/authentication/test_api_key_token.py (3)

20-44: LGTM! Success case properly tested.

The test correctly validates successful authentication when a valid Bearer token matching the configured API key is provided. All returned values are properly asserted.


47-76: LGTM! Missing Authorization header case properly tested.

The test correctly validates that an HTTPException with status 401 is raised when no Authorization header is present. The assertion structure matches the expected error format.


78-99: LGTM! Malformed Authorization header case properly tested.

The test correctly validates that an HTTPException with status 401 is raised when the Authorization header doesn't use the Bearer scheme. The test covers an important security validation.

@romartin
Copy link
Contributor Author

romartin commented Dec 2, 2025

Added more tests, applied suggestions and code reformatted.

So as far as I am concerned, just pending on feedback on these comments from @eranco74 , please let me know your thoughts, they may imply code changes:

Thanks!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/authentication/api_key_token.py (1)

6-6: Correct the module docstring return tuple.

The docstring still states the return tuple has DEFAULT_USER_NAME twice, but the actual return at line 72 is (DEFAULT_USER_UID, DEFAULT_USER_NAME, self.skip_userid_check, user_token). The first element should be DEFAULT_USER_UID, not DEFAULT_USER_NAME.

Apply this diff:

-- Returns a tuple: (DEFAULT_USER_NAME, DEFAULT_USER_NAME, skip_userid_check, user_token).
+- Returns a tuple: (DEFAULT_USER_UID, DEFAULT_USER_NAME, skip_userid_check, user_token).
🧹 Nitpick comments (1)
tests/unit/models/config/test_authentication_configuration.py (1)

380-392: Consider adding a test for accessing api_key_configuration with the wrong module.

The test coverage is good, but consider adding a test similar to lines 46-50 that verifies ValueError is raised when accessing auth_config.api_key_configuration with a non-API-key-token module (e.g., AUTH_MOD_NOOP).

Example test:

def test_authentication_configuration_api_key_wrong_module() -> None:
    """Test that accessing api_key_configuration with wrong module raises ValueError."""
    auth_config = AuthenticationConfiguration(
        module=AUTH_MOD_NOOP,
        skip_tls_verification=False,
        k8s_ca_cert_path=None,
        k8s_cluster_api=None,
    )
    
    with pytest.raises(
        ValueError,
        match="API Key configuration is only available for API Key token authentication module",
    ):
        _ = auth_config.api_key_configuration
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc6b447 and b3c968d.

📒 Files selected for processing (5)
  • src/authentication/__init__.py (2 hunks)
  • src/authentication/api_key_token.py (1 hunks)
  • src/models/config.py (4 hunks)
  • tests/unit/authentication/test_api_key_token.py (1 hunks)
  • tests/unit/models/config/test_authentication_configuration.py (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/unit/authentication/test_api_key_token.py
  • src/authentication/init.py
🧰 Additional context used
📓 Path-based instructions (5)
src/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/**/*.py: Use absolute imports for internal modules in LCS project (e.g., from auth import get_auth_dependency)
All modules must start with descriptive docstrings explaining their purpose
Use logger = logging.getLogger(__name__) pattern for module logging
All functions must include complete type annotations for parameters and return types, using modern syntax (str | int) and Optional[Type] or Type | None
All functions must have docstrings with brief descriptions following Google Python docstring conventions
Function names must use snake_case with descriptive, action-oriented names (get_, validate_, check_)
Avoid in-place parameter modification anti-patterns; return new data structures instead of modifying input parameters
Use async def for I/O operations and external API calls
All classes must include descriptive docstrings explaining their purpose following Google Python docstring conventions
Class names must use PascalCase with descriptive names and standard suffixes: Configuration for config classes, Error/Exception for exceptions, Resolver for strategy patterns, Interface for abstract base classes
Abstract classes must use ABC with @abstractmethod decorators
Include complete type annotations for all class attributes in Python classes
Use import logging and module logger pattern with standard log levels: debug, info, warning, error

Files:

  • src/authentication/api_key_token.py
  • src/models/config.py
tests/{unit,integration}/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

tests/{unit,integration}/**/*.py: Use pytest for all unit and integration tests; do not use unittest framework
Unit tests must achieve 60% code coverage; integration tests must achieve 10% coverage

Files:

  • tests/unit/models/config/test_authentication_configuration.py
tests/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Use pytest-mock with AsyncMock objects for mocking in tests

Files:

  • tests/unit/models/config/test_authentication_configuration.py
src/models/config.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/models/config.py: All configuration must use Pydantic models extending ConfigurationBase with extra="forbid" to reject unknown fields
Use type hints Optional[FilePath], PositiveInt, SecretStr for Pydantic configuration models

Files:

  • src/models/config.py
src/models/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/models/**/*.py: Use @field_validator and @model_validator for custom validation in Pydantic models
Pydantic configuration classes must extend ConfigurationBase; data models must extend BaseModel

Files:

  • src/models/config.py
🧠 Learnings (4)
📚 Learning: 2025-11-24T16:58:04.410Z
Learnt from: CR
Repo: lightspeed-core/lightspeed-stack PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:58:04.410Z
Learning: Applies to src/**/*.py : All classes must include descriptive docstrings explaining their purpose following Google Python docstring conventions

Applied to files:

  • src/authentication/api_key_token.py
📚 Learning: 2025-11-24T16:58:04.410Z
Learnt from: CR
Repo: lightspeed-core/lightspeed-stack PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:58:04.410Z
Learning: Applies to src/models/config.py : All configuration must use Pydantic models extending `ConfigurationBase` with `extra="forbid"` to reject unknown fields

Applied to files:

  • tests/unit/models/config/test_authentication_configuration.py
📚 Learning: 2025-11-24T16:58:04.410Z
Learnt from: CR
Repo: lightspeed-core/lightspeed-stack PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:58:04.410Z
Learning: Applies to src/models/config.py : Use type hints `Optional[FilePath]`, `PositiveInt`, `SecretStr` for Pydantic configuration models

Applied to files:

  • tests/unit/models/config/test_authentication_configuration.py
  • src/models/config.py
📚 Learning: 2025-09-02T11:09:40.404Z
Learnt from: radofuchs
Repo: lightspeed-core/lightspeed-stack PR: 485
File: tests/e2e/features/environment.py:87-95
Timestamp: 2025-09-02T11:09:40.404Z
Learning: In the lightspeed-stack e2e tests, noop authentication tests use the default lightspeed-stack.yaml configuration, while noop-with-token tests use the Authorized tag to trigger a config swap to the specialized noop-with-token configuration file.

Applied to files:

  • tests/unit/models/config/test_authentication_configuration.py
🧬 Code graph analysis (2)
src/authentication/api_key_token.py (4)
src/authentication/interface.py (1)
  • AuthInterface (34-39)
src/authentication/utils.py (1)
  • extract_user_token (8-30)
src/log.py (1)
  • get_logger (7-13)
src/models/config.py (2)
  • config (279-285)
  • APIKeyTokenConfiguration (703-715)
tests/unit/models/config/test_authentication_configuration.py (1)
src/models/config.py (3)
  • APIKeyTokenConfiguration (703-715)
  • AuthenticationConfiguration (718-795)
  • api_key_configuration (787-795)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: e2e_tests (azure)
  • GitHub Check: e2e_tests (ci)
🔇 Additional comments (6)
src/authentication/api_key_token.py (1)

9-72: LGTM!

The implementation follows security best practices:

  • Uses secrets.compare_digest for constant-time comparison to prevent timing attacks
  • Properly accesses the SecretStr via get_secret_value()
  • Includes complete type annotations and Google-style docstrings
  • Follows the established authentication interface pattern
tests/unit/models/config/test_authentication_configuration.py (1)

356-378: LGTM!

The test properly validates the API key token authentication configuration, including:

  • Correct module assignment
  • SecretStr usage for the API key
  • Property accessor validation (api_key_configuration)
  • Field presence verification
src/models/config.py (4)

703-716: LGTM!

The APIKeyTokenConfiguration class properly:

  • Extends ConfigurationBase (which enforces extra="forbid")
  • Uses SecretStr to prevent accidental exposure in logs/errors
  • Includes proper Field configuration with min_length=1 validation
  • Provides JSON schema metadata for API documentation

As per coding guidelines, SecretStr is correctly used for sensitive configuration fields.


752-761: LGTM!

The validation logic correctly enforces that:

  • api_key_config is provided when using API key token authentication
  • The api_key field is present (though line 757's check is technically redundant due to Pydantic's min_length=1 constraint, it serves as defensive programming)

786-796: LGTM!

The api_key_configuration property accessor:

  • Follows the established pattern used by jwk_configuration and rh_identity_configuration
  • Includes proper validation with clear error messages
  • Has complete type annotations
  • Ensures type safety when accessing the API key configuration

726-726: LGTM!

The api_key_config field is properly integrated into AuthenticationConfiguration, following the same pattern as jwk_config and rh_identity_config.

@romartin romartin changed the title API Key (Bearer) token auth module. AAP-59476: API Key (Bearer) token auth module. Dec 2, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/authentication/api_key_token.py (1)

1-7: Fix the module docstring - previous correction was not applied.

The module docstring on line 6 still incorrectly states the return tuple as (DEFAULT_USER_NAME, DEFAULT_USER_NAME, skip_userid_check, user_token). The actual return on line 74 is (DEFAULT_USER_UID, DEFAULT_USER_NAME, skip_userid_check, user_token).

This was flagged in a previous review and marked as "done", but the fix was not correctly applied. The first element should be DEFAULT_USER_UID, not DEFAULT_USER_NAME.

Apply this diff:

 """Authentication flow for FastAPI endpoints with a provided API key.
 
 Behavior:
 - Reads a user token from request headers via `authentication.utils.extract_user_token` and verifies
 the value equals to the API Key, given from configuration parameter.
-- Returns a tuple: (DEFAULT_USER_NAME, DEFAULT_USER_NAME, skip_userid_check, user_token).
+- Returns a tuple: (DEFAULT_USER_UID, DEFAULT_USER_NAME, skip_userid_check, user_token).
 """
🧹 Nitpick comments (1)
src/models/config.py (1)

752-761: Consider removing the redundant None check.

The check on line 758 for api_key.get_secret_value() is None is redundant. Since api_key is a required field with min_length=1 validation (line 708), Pydantic ensures it cannot be None or empty. The validation on line 753 (checking if api_key_config is None) is sufficient.

Additionally, this creates an inconsistency with the JWK and RH Identity validation logic (lines 739-750), which only check if the config object is None, not the inner fields.

You can simplify this to match the pattern used for other authentication modules:

         if self.module == constants.AUTH_MOD_APIKEY_TOKEN:
             if self.api_key_config is None:
                 raise ValueError(
                     "API Key configuration section must be specified "
                     "when using API Key token authentication"
                 )
-            if self.api_key_config.api_key.get_secret_value() is None:
-                raise ValueError(
-                    "api_key parameter must be specified when using API_KEY token authentication"
-                )
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b3c968d and 234b269.

📒 Files selected for processing (4)
  • src/authentication/api_key_token.py (1 hunks)
  • src/models/config.py (4 hunks)
  • tests/unit/authentication/test_api_key_token.py (1 hunks)
  • tests/unit/models/config/test_authentication_configuration.py (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/unit/authentication/test_api_key_token.py
🧰 Additional context used
📓 Path-based instructions (5)
tests/{unit,integration}/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

tests/{unit,integration}/**/*.py: Use pytest for all unit and integration tests; do not use unittest framework
Unit tests must achieve 60% code coverage; integration tests must achieve 10% coverage

Files:

  • tests/unit/models/config/test_authentication_configuration.py
tests/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Use pytest-mock with AsyncMock objects for mocking in tests

Files:

  • tests/unit/models/config/test_authentication_configuration.py
src/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/**/*.py: Use absolute imports for internal modules in LCS project (e.g., from auth import get_auth_dependency)
All modules must start with descriptive docstrings explaining their purpose
Use logger = logging.getLogger(__name__) pattern for module logging
All functions must include complete type annotations for parameters and return types, using modern syntax (str | int) and Optional[Type] or Type | None
All functions must have docstrings with brief descriptions following Google Python docstring conventions
Function names must use snake_case with descriptive, action-oriented names (get_, validate_, check_)
Avoid in-place parameter modification anti-patterns; return new data structures instead of modifying input parameters
Use async def for I/O operations and external API calls
All classes must include descriptive docstrings explaining their purpose following Google Python docstring conventions
Class names must use PascalCase with descriptive names and standard suffixes: Configuration for config classes, Error/Exception for exceptions, Resolver for strategy patterns, Interface for abstract base classes
Abstract classes must use ABC with @abstractmethod decorators
Include complete type annotations for all class attributes in Python classes
Use import logging and module logger pattern with standard log levels: debug, info, warning, error

Files:

  • src/models/config.py
  • src/authentication/api_key_token.py
src/models/config.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/models/config.py: All configuration must use Pydantic models extending ConfigurationBase with extra="forbid" to reject unknown fields
Use type hints Optional[FilePath], PositiveInt, SecretStr for Pydantic configuration models

Files:

  • src/models/config.py
src/models/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/models/**/*.py: Use @field_validator and @model_validator for custom validation in Pydantic models
Pydantic configuration classes must extend ConfigurationBase; data models must extend BaseModel

Files:

  • src/models/config.py
🧠 Learnings (4)
📚 Learning: 2025-11-24T16:58:04.410Z
Learnt from: CR
Repo: lightspeed-core/lightspeed-stack PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:58:04.410Z
Learning: Applies to src/models/config.py : All configuration must use Pydantic models extending `ConfigurationBase` with `extra="forbid"` to reject unknown fields

Applied to files:

  • tests/unit/models/config/test_authentication_configuration.py
📚 Learning: 2025-11-24T16:58:04.410Z
Learnt from: CR
Repo: lightspeed-core/lightspeed-stack PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:58:04.410Z
Learning: Applies to src/models/config.py : Use type hints `Optional[FilePath]`, `PositiveInt`, `SecretStr` for Pydantic configuration models

Applied to files:

  • tests/unit/models/config/test_authentication_configuration.py
  • src/models/config.py
📚 Learning: 2025-09-02T11:09:40.404Z
Learnt from: radofuchs
Repo: lightspeed-core/lightspeed-stack PR: 485
File: tests/e2e/features/environment.py:87-95
Timestamp: 2025-09-02T11:09:40.404Z
Learning: In the lightspeed-stack e2e tests, noop authentication tests use the default lightspeed-stack.yaml configuration, while noop-with-token tests use the Authorized tag to trigger a config swap to the specialized noop-with-token configuration file.

Applied to files:

  • tests/unit/models/config/test_authentication_configuration.py
📚 Learning: 2025-11-24T16:58:04.410Z
Learnt from: CR
Repo: lightspeed-core/lightspeed-stack PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:58:04.410Z
Learning: Applies to src/**/*.py : All classes must include descriptive docstrings explaining their purpose following Google Python docstring conventions

Applied to files:

  • src/authentication/api_key_token.py
🧬 Code graph analysis (1)
tests/unit/models/config/test_authentication_configuration.py (1)
src/models/config.py (3)
  • APIKeyTokenConfiguration (703-715)
  • AuthenticationConfiguration (718-796)
  • api_key_configuration (788-796)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: build-pr
  • GitHub Check: unit_tests (3.12)
  • GitHub Check: Pylinter
  • GitHub Check: e2e_tests (ci)
  • GitHub Check: e2e_tests (azure)
🔇 Additional comments (6)
src/models/config.py (2)

703-715: LGTM! SecretStr usage addresses previous feedback.

The APIKeyTokenConfiguration class correctly uses SecretStr for the api_key field to prevent accidental exposure in logs or error messages. The field validation with min_length=1 and JSON schema metadata (format: password, writeOnly: true) are appropriate for sensitive configuration data.


787-796: LGTM! Property accessor follows established patterns.

The api_key_configuration property correctly follows the same implementation pattern as jwk_configuration and rh_identity_configuration, ensuring consistency across authentication module accessors.

src/authentication/api_key_token.py (2)

26-33: LGTM! Class docstring follows guidelines.

The class docstring correctly describes the purpose and behavior of APIKeyTokenAuthDependency, following Google Python docstring conventions as required by the coding guidelines.


35-74: LGTM! Authentication implementation is secure and well-documented.

The implementation correctly:

  • Documents parameters and return values following Google Python conventions
  • Uses secrets.compare_digest() for constant-time comparison to prevent timing attacks
  • Properly extracts the secret value from SecretStr using get_secret_value()
  • Returns the correct 4-tuple with user authentication information
tests/unit/models/config/test_authentication_configuration.py (2)

356-378: LGTM! Test coverage follows established patterns.

The test correctly validates:

  • API key token authentication configuration creation
  • Property accessor functionality via api_key_configuration
  • Field accessibility and proper SecretStr usage

The implementation follows the same testing pattern used for JWK and RH Identity authentication modules, ensuring consistency across the test suite.


380-393: LGTM! Error case is properly tested.

The test correctly validates that a ValidationError is raised with the appropriate message when api_key_config is not provided but the authentication module is set to AUTH_MOD_APIKEY_TOKEN. This follows the same validation pattern used for other authentication modules.

@romartin
Copy link
Contributor Author

romartin commented Dec 3, 2025

/ok-to-test

@openshift-ci
Copy link

openshift-ci bot commented Dec 3, 2025

@romartin: Cannot trigger testing until a trusted user reviews the PR and leaves an /ok-to-test message.

Details

In response to this:

/ok-to-test

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@tisnik
Copy link
Contributor

tisnik commented Dec 3, 2025

/ok-to-test

@romartin
Copy link
Contributor Author

romartin commented Dec 3, 2025

thank you @tisnik !

@tisnik
Copy link
Contributor

tisnik commented Dec 3, 2025

/ok-to-test

Copy link
Contributor

@tisnik tisnik left a comment

Choose a reason for hiding this comment

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

LGTM

@tisnik tisnik merged commit 2c8148f into lightspeed-core:main Dec 4, 2025
21 of 23 checks passed
@romartin
Copy link
Contributor Author

romartin commented Dec 4, 2025

thank you all!!

@romartin romartin deleted the AAP-59476-apikey-baerer-auth-module branch December 4, 2025 11:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants