Skip to content

Reimplement: feat(auth): Implement issuer allow-list and required-auth flag #4798

@clockwork-labs-bot

Description

@clockwork-labs-bot

This issue tracks reimplementation of the work from stale PR #2847, which is being closed because it is too out of date to merge directly.

    Original PR: https://github.com/clockworklabs/SpacetimeDB/pull/2847
    Original author: @ImGajeed76
    Original branch: `feat/jwt-issuer-validation`
    Base branch: `master`

    ## Original PR summary

    # Description of Changes

This PR introduces critical security enhancements to the JWT authentication and authorization flow, hardening the server for production environments.

  1. Issuer Allow-List: A new --allowed-oidc-issuer CLI flag has been added. It can be specified multiple times to build a whitelist of trusted OIDC providers. The validation logic now checks the token's iss claim against this list before proceeding with OIDC validation. If the list is not configured, a prominent security warning is logged at startup to alert operators of the permissive default.

  2. Required Authentication: A new --auth-required CLI flag has been added to disable the on-the-fly creation of anonymous users. When this flag is enabled, any connection attempt that does not present a valid JWT will be rejected with a 401 Unauthorized error. This is a crucial feature for private or permissioned deployments.

  3. Authentication Flow Fix: A logic bug in the anon_auth_middleware has been corrected. Previously, a request with an invalid token would fail validation but would then incorrectly fall back to the anonymous user creation flow. The logic has been refactored to ensure that an invalid token immediately terminates the request with a 401 Unauthorized error, correctly distinguishing it from a request that provides no token at all.

These changes are plumbed through the application stack, from the start subcommand's CLI parsing, through the StandaloneEnv state, and into the auth module where the logic is enforced.

API and ABI breaking changes

There are no external API or ABI breaking changes for clients interacting with the server. The new CLI flags are additive and the server's default behavior remains the same (though now with a security warning). Internal function signatures for StandaloneEnv::init and default_auth_environment have changed, but these are not part of the public-facing API.

Expected complexity level and risk

Complexity: 2/5

The changes touch several core files (start.rs, main.rs, auth.rs, token_validation.rs), but the logic itself is straightforward. The primary complexity lies in correctly plumbing the configuration from the CLI down to the middleware where it is used.

The risk is low to moderate. The main risk is an incorrect implementation of the authentication flow, which could either improperly reject valid users or improperly accept invalid ones. However, the new logic is more explicit and robust than the previous implementation, reducing the overall risk profile of the auth system. The default behavior is unchanged, minimizing the impact on existing development workflows.

Testing

Manual testing has been performed to validate the new functionality:

  • Started the server with --allowed-oidc-issuer https://accounts.google.com. Verified that a token from a different issuer is rejected, while a connection with no token still succeeds (creates an anonymous user).
  • Started the server with --auth-required. Verified that a connection attempt with no token is rejected with a 401 Unauthorized error.
  • Started the server with no new flags. Verified that a request with a deliberately invalid/expired token is rejected with a 401 Unauthorized error and does not create an anonymous user.
  • Verified that the security warning for a missing issuer allow-list is logged correctly at startup.

Reviewers are encouraged to sanity-check these flows, particularly the interaction between the --auth-required flag and the subscribe endpoint.

    ## Follow-up

    - Reimplement this change in a fresh PR against current `master`.
    - Carry forward any still-relevant context from the original PR discussion and review.
    - Link the new implementation PR back to the original stale PR for historical context.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions