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.
-
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.
-
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.
-
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:
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.
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.
This PR introduces critical security enhancements to the JWT authentication and authorization flow, hardening the server for production environments.
Issuer Allow-List: A new
--allowed-oidc-issuerCLI 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'sissclaim 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.Required Authentication: A new
--auth-requiredCLI 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 a401 Unauthorizederror. This is a crucial feature for private or permissioned deployments.Authentication Flow Fix: A logic bug in the
anon_auth_middlewarehas 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 a401 Unauthorizederror, correctly distinguishing it from a request that provides no token at all.These changes are plumbed through the application stack, from the
startsubcommand's CLI parsing, through theStandaloneEnvstate, and into theauthmodule 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::initanddefault_auth_environmenthave 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:
--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).--auth-required. Verified that a connection attempt with no token is rejected with a401 Unauthorizederror.401 Unauthorizederror and does not create an anonymous user.Reviewers are encouraged to sanity-check these flows, particularly the interaction between the
--auth-requiredflag and thesubscribeendpoint.