Skip to content

feat(auth): add OIDC authentication middleware#70

Draft
aparajon wants to merge 1 commit intomainfrom
oidc-auth
Draft

feat(auth): add OIDC authentication middleware#70
aparajon wants to merge 1 commit intomainfrom
oidc-auth

Conversation

@aparajon
Copy link
Copy Markdown
Collaborator

@aparajon aparajon commented May 1, 2026

Summary

Add optional OIDC authentication middleware for SchemaBot's API endpoints, with a local Dex OIDC provider for testing.

Server-side auth (pkg/auth/):

  • Authorizer interface with NoneAuthorizer (default) and OIDCAuthorizer
  • JWT validation via JWKS discovery (coreos/go-oidc/v3) — works with any OIDC provider
  • Read endpoints (status, logs, progress) require any valid token
  • Write endpoints (plan, apply, cutover) require admin group membership
  • Webhook and health endpoints bypass auth
  • Backwards compatible — disabled when auth config is not set

Local testing with Dex:

  • docker compose --profile oidc up starts Dex + auth-enabled SchemaBot
  • Two test users: admin@example.com (write access) and viewer@example.com (read-only)
  • Token helper script: ./scripts/get-oidc-token.sh
  • Auth-enabled SchemaBot on port 13380, unauthenticated on 13370 (side by side)
# Enable OIDC (optional)
auth:
  type: oidc
  issuer: "https://accounts.google.com"
  admin_group: schema-admins

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings May 1, 2026 22:13
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds optional, configurable OIDC-based authentication/authorization middleware to SchemaBot’s HTTP API. When enabled, requests must present a valid JWT (via OIDC discovery/JWKS), and write operations require membership in a configured admin group; when disabled, behavior remains fully open as today.

Changes:

  • Introduces pkg/auth with an Authorizer interface plus NoneAuthorizer (default) and OIDCAuthorizer implementations.
  • Wires the authorizer middleware into the HTTP server startup and adds auth configuration + validation in pkg/api/config.go.
  • Adds unit tests covering OIDC validation, group-based authorization, excluded paths, and context helpers.

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
pkg/cmd/commands/serve.go Builds the configured authorizer and wraps the HTTP mux with auth middleware before OTel instrumentation.
pkg/auth/auth.go Defines the Authorizer interface for HTTP middleware-based auth.
pkg/auth/context.go Adds User + context helpers (WithUser, UserFromContext) for downstream handlers.
pkg/auth/none.go Implements a no-op authorizer that injects an anonymous user.
pkg/auth/oidc.go Implements OIDC discovery/JWT verification + admin-group enforcement for write endpoints; skips auth for infra/webhook paths.
pkg/auth/context_test.go Tests user context set/get helpers.
pkg/auth/none_test.go Tests no-op authorizer behavior.
pkg/auth/oidc_test.go Tests token validation, expiry, admin-group enforcement, excluded paths, and custom groups claim.
pkg/auth/config_test.go Tests validation behavior for api.AuthConfig.
pkg/api/config.go Adds Auth config block and validation for supported auth types and required fields.
go.mod / go.sum Adds OIDC + JOSE dependencies (coreos/go-oidc/v3, go-jose/go-jose/v4).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/cmd/commands/serve.go
// Set up authentication middleware based on config.
// The auth middleware wraps the mux so it runs before any handler.
// Webhook/health/metrics endpoints are excluded within the middleware itself.
authz, err := buildAuthorizer(ctx, serverConfig.Auth, logger)
Comment thread pkg/auth/oidc.go
raw, ok := claims[a.groupsClaim]
if !ok {
// Groups claim not present — the user has no group memberships.
return nil, nil
Comment thread pkg/auth/oidc.go
func writeAuthError(w http.ResponseWriter, status int, message string) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
resp := map[string]string{"error": message}
Comment thread pkg/auth/oidc.go
Comment on lines +214 to +216
if err := json.NewEncoder(w).Encode(resp); err != nil {
slog.Error("failed to write auth error response", "error", err)
}
Comment thread pkg/api/config.go
}
return nil
default:
return fmt.Errorf("unknown auth type %q (supported: oidc)", a.Type)
Add optional OIDC authentication for SchemaBot's API endpoints. When
configured, requires valid JWT tokens for API access and restricts
write operations to members of a configured admin group.

Server-side auth (pkg/auth/):
- Authorizer interface with NoneAuthorizer (default) and OIDCAuthorizer
- JWT validation via JWKS discovery (coreos/go-oidc/v3)
- Read endpoints require any valid token, write endpoints require admin group
- Webhook and health endpoints bypass auth
- Fully backwards compatible — disabled by default

Local testing with Dex:
- Dex OIDC provider in docker-compose (--profile oidc)
- Two test users: admin (write access) and viewer (read-only)
- Token helper script for browser-based auth flow
- Separate schemabot-oidc service on port 13380

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

2 participants