Conversation
5-step plan covering config, refresh token store/generation, OpenAPI spec updates, HTTP handler wiring, and comprehensive tests. Also enriches CLAUDE.md with important file paths and token flow details for step agents. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace in-memory refresh token cache with database-backed storage layer - Add refresh_token table schema to database/schema.go plan - Add RefreshTokenRepository interface and SqlRefreshTokenRepository to database/repository.go plan - Add RefreshTokenRow model to database/models.go plan - Add database repository tests to Step 5 - Require database connection when RefreshTokenEnabled is true (fail fast at startup) - Ensure tokens survive restarts and support horizontal scaling Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…-34/plan into ticket-34/work Reviewed-on: http://localhost:3001/general-agent-4/VCVerifier/pulls/1 Reviewed-by: wistefan <wistefan@dev-env.local>
Add RefreshTokenEnabled (bool, default false) and RefreshTokenExpiration (int, default 2880 minutes / 48 hours) to the Verifier config struct, along with a DefaultRefreshTokenExpirationMinutes named constant. Add TYPE_REFRESH_TOKEN = "refresh_token" grant type constant to common/metadata.go. Update existing config test expectations and add a dedicated TestRefreshTokenConfigDefaults test with a YAML fixture covering both default and explicit value parsing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ion and constants' (#2) from ticket-34/step-1 into ticket-34/work Reviewed-on: http://localhost:3001/general-agent-4/VCVerifier/pulls/2 Reviewed-by: wistefan <wistefan@dev-env.local>
Implement Step 2 of the refresh token feature: database-backed storage for refresh tokens with single-use semantics and token rotation. - Add refresh_token table DDL to schema.go (PostgreSQL, MySQL, SQLite) - Add RefreshTokenRow model with JSON serialization helpers for scopes and credentials - Add RefreshTokenRepository interface and SqlRefreshTokenRepository with StoreRefreshToken, GetAndDeleteRefreshToken, DeleteExpiredTokens - Add ExchangeRefreshToken, CreateRefreshToken, IsRefreshTokenEnabled to the Verifier interface and CredentialVerifier implementation - Wire up refresh token repo in main.go when feature is enabled - Add comprehensive tests for repository (SQLite), verifier methods, and model serialization helpers Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Store full signed JWT string in RefreshTokenRow.JWTPayload instead of decomposed fields, so access tokens can be re-issued without re-applying credential inclusion configurations - Remove erroneous TestRefreshTokenFlatClaims_True test (FlatClaims belongs to ScopeEntryRow, not RefreshTokenRow) - Fix JWTPayload field documentation to accurately describe compact JWT serialization storage Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…token store and generation logic' (#3) from ticket-34/step-2 into ticket-34/work Reviewed-on: http://localhost:3001/general-agent-4/VCVerifier/pulls/3 Reviewed-by: wistefan <wistefan@dev-env.local>
Update TokenResponse struct with RefreshToken field (omitempty for backward compatibility) and extend the OpenAPI spec to document the new refresh_token grant type in TokenRequest and refresh_token field in both TokenRequest and TokenResponse schemas. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…and OpenAPI spec' (#4) from ticket-34/step-3 into ticket-34/work Reviewed-on: http://localhost:3001/general-agent-4/VCVerifier/pulls/4 Reviewed-by: wistefan <wistefan@dev-env.local>
Connect refresh token generation and exchange to the HTTP layer: - Add grant_type=refresh_token handler that exchanges a valid refresh token for a new access token and rotated refresh token - Extend GetToken (authorization_code flow) to generate and return refresh tokens when the feature is enabled - Extend verifiyVPToken (vp_token and token-exchange flows) to include refresh tokens in responses when enabled - Add IsRefreshTokenEnabled() and CreateRefreshToken() to Verifier interface, called from the openapi layer - Store clientId in tokenStore so refresh tokens can be created during authorization_code exchange - Add comprehensive tests for all refresh token paths including enabled/disabled states, error propagation, and all grant types Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…n endpoint handlers' (#5) from ticket-34/step-4 into ticket-34/work Reviewed-on: http://localhost:3001/general-agent-4/VCVerifier/pulls/5 Reviewed-by: wistefan <wistefan@dev-env.local>
Cover all refresh token scenarios across three packages: - database: field round-trip, token isolation, mixed-expiry cleanup, table-driven store/retrieve, MySQL adapt - verifier: table-driven ExchangeRefreshToken (enabled/disabled/expired/ error paths), multi-chain rotation, CreateRefreshToken with expiration timestamp and enabled/disabled, RS256 signToken, rotation store failure - openapi: disabled grant types omit refresh_token, CreateRefreshToken failure degrades gracefully (access token still returned) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…esh token flows' (#6) from ticket-34/step-5 into ticket-34/work Reviewed-on: http://localhost:3001/general-agent-4/VCVerifier/pulls/6 Reviewed-by: wistefan <wistefan@dev-env.local>
Groups RefreshTokenEnabled and RefreshTokenExpiration into a dedicated RefreshToken struct, accessed as verifier.refreshToken.enabled/expiration in YAML. Defaults (enabled=false, expiration=2880) are preserved.
Tokens are now always stored as HMAC-SHA256 hex digests. The HMAC key (salt) can be provided via refreshToken.hashSalt in server.yaml for stability across restarts; when absent a random salt is generated at startup, invalidating all tokens on restart. A token_suffix column (VARCHAR 5) is added to the refresh_token table, always storing the last 5 characters of the raw token for operational identification regardless of hashing.
…egrity Replace the full signed access token stored in the refresh_token table with the raw JWT claims (base64url-decoded payload segment) to avoid persisting a usable bearer token in the database. Add HMAC-SHA256 integrity protection computed by the repository using the existing hash salt, binding the raw refresh token value to its stored claims and client ID. Tampering is detected on retrieval (after consuming the token to prevent replay) and returns a warning log plus a 403 via the existing ErrorRefreshTokenInvalidSignature path.
…n files Separates SqlServiceRepository and SqlRefreshTokenRepository into their own files within the same package to improve readability and cohesion.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Added OAuth2 refresh token support to VCVerifier's token endpoint, per RFC 6749 Section 1.5. The feature is opt-in via configuration so existing deployments are unaffected.