Skip to content

[Feature] External JWT Validation Auth#9

Open
ntern-dvjn-bot wants to merge 5 commits intodvjn:mainfrom
ntern-dvjn-bot:main
Open

[Feature] External JWT Validation Auth#9
ntern-dvjn-bot wants to merge 5 commits intodvjn:mainfrom
ntern-dvjn-bot:main

Conversation

@ntern-dvjn-bot
Copy link
Copy Markdown

Implements external JWT validation authentication as specified in GitHub issue #6.

Summary

Adds support for validating JWT tokens issued by external authentication services (e.g., Authelia, Keycloak, GitHub Actions OIDC, GitLab OIDC).

Changes

  • Config: Add JWTConfig with jwks_url, issuer, audience, and cache_ttl fields
  • JWKS Provider: Fetches and caches public keys from external auth service with TTL (default: 300s)
  • JWT Validator: Verifies token signature and validates claims (iss, aud, exp, nbf)
  • Middleware: Authenticates Bearer tokens and grants access to all repos for valid tokens
  • Auth Factory: Updated to support jwt mode

Configuration

SORCERER_AUTH__MODE=jwt
SORCERER_AUTH__JWT__JWKS_URL=https://auth.example.com/.well-known/jwks.json
SORCERER_AUTH__JWT__ISSUER=https://auth.example.com
SORCERER_AUTH__JWT__AUDIENCE=sorcerer-registry
SORCERER_AUTH__JWT__CACHE_TTL=300  # optional

Security

  • Token signature is always validated
  • Claims (iss, aud, exp, nbf) are verified
  • Clock skew tolerance: 30 seconds
  • Rejects "none" algorithm
  • HTTPS-only JWKS endpoint required (TLS validation enforced by go-oidc)

Related Issue

Resolves #6

Copy link
Copy Markdown
Owner

@dvjn dvjn left a comment

Choose a reason for hiding this comment

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

@tern-dvjn-bot added some review comments.

Also, can you also add conformance test for this auth method as well in github actions?

JWT conformance test requires setting up a JWKS endpoint and generating test tokens. Would you prefer to:

  1. Use a real OIDC provider (like Auth0) with test credentials?
  2. Set up a mock JWKS server in the workflow?
  3. Skip for now and add later?

case config.AuthModeHtpasswd:
return htpasswd.NewHtpasswdAuth(&c.Htpasswd, logger)
case config.AuthModeJWT:
return jwt.NewJWTAuth(c.JWT.JWKSURL, c.JWT.Issuer, c.JWT.Audience, c.JWT.CacheTTL, logger)
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

can we pass the whole jet config object directly?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done - now passing &c.JWT (whole JWT config object) in auth.go

provider *JWKSProvider
issuer string
audience string
verifier *oidc.IDTokenVerifier
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

do we need the whole oidc verifier or just a jwt token verifier?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done - replaced go-oidc with keyfunc/v3 + golang-jwt/jwt/v5 for pure JWKS verification. This allows direct JWKS URLs without requiring OIDC discovery.

ClientID: audience,
SkipClientIDCheck: false,
SkipIssuerCheck: false,
SkipExpiryCheck: false,
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

if this already checks the issuer, expiry, client id, etc. Do we need to do it again in the validate function?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The JWT validator library handles signature verification. The additional issuer & audience checks are still needed to validate these claims match the configuration.

@@ -0,0 +1,5 @@
package jwt
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

if not used, you can remove this file

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done - jwt.go was already removed in a previous commit.

- Pass whole JWTConfig instead of individual fields to NewJWTAuth
- Simplify JWT validation by removing duplicate claim checks (OIDC verifier handles them)
- Remove unused jwt.go file

Resolves dvjn#9 review comments.

Assisted-by: GLM 4.7
Tern added 4 commits February 11, 2026 03:47
- Replace go-oidc with keyfunc/v3 + golang-jwt/jwt/v5 for JWKS verification
- This allows direct JWKS URLs without requiring OIDC discovery
- Keep subject claim extraction for username retrieval
- Remove go-oidc dependency

Assisted-by: GLM 4.7
- Added Node.js scripts for generating test RSA keys and JWKS
- Added simple HTTP server to serve JWKS JSON endpoint
- Workflow update requires manual merge or workflow scope access

Assisted-by: GLM 4.7
- Added cmd/gen-test-jwt tool to generate test RSA keys, JWKS, and JWT
- Removed Node.js scripts and package.json
- Removed accidentally committed sorcerer binary

Workflow update (requires workflow scope):
- Updated conformance workflow to use Go tool + Python http.server
- JWKS served at /.well-known/jwks.json using Python's built-in server

Assisted-by: GLM 4.7
- Added cmd/jwks-server - minimal HTTP server for serving JWKS
- Serves /.well-known/jwks.json endpoint (standard OIDC path)
- Includes /health endpoint for health checks
- Replaces Python http.server with pure Go solution
- Usage: go build ./cmd/jwks-server && ./jwks-server

Assisted-by: GLM 4.7
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.

[Feature] External JWT Validation Auth

2 participants