Bidirectional Compatibility Patterns
To guarantee that a schema change can be rolled back without invalidating tokens issued during the deployment window, you must decouple the physical storage schema from the logical token validation. The most effective pattern is the Additive-Only Migration combined with Graceful Degradation.
1. Additive-Only Schema Changes
Never modify or delete existing columns during a forward migration. To introduce a change:
- Adding Data: Create new columns as
NULLABLE. The Authorization Server (AS) begins writing to both the old and new columns.
- Changing Types: Create a new column with the desired type (e.g.,
token_metadata_v2) rather than altering the existing column.
Because the old columns remain untouched and populated, a rollback of the AS code will simply result in the system ignoring the new columns, while the old logic continues to find the data it expects.
2. Resource Server (RS) Tolerance
The Resource Server must be programmed to treat new schema attributes as optional. If the RS uses token introspection, the introspection endpoint should be configured to return a stable set of claims regardless of the underlying storage version. If the RS validates tokens locally (e.g., JWTs), it should ignore unknown claims rather than throwing a validation error.
Verification Without Version-Specific Code
To verify that tokens issued under the new schema remain valid after a rollback without writing if (version == 2) blocks, use Cross-Version Integration Testing:
- Forward Test: Deploy the new AS. Issue a token. Verify the RS accepts it.
- Rollback Test: Revert the AS to the previous version. Attempt to validate the token issued in Step 1.
- Success Criteria: The token must remain valid because the AS (now rolled back) still sees the original columns/claims that were preserved during the additive migration.
Safe Defaults and Nullability
To eliminate coordinated downtime, adopt these defaults:
- Nullable Columns: All new columns must be nullable. This ensures that the old AS version can still perform
INSERT operations without knowing about the new fields.
- Default Values: Use database-level defaults for new columns to ensure that the old AS doesn't leave the database in an inconsistent state that the new AS cannot handle upon redeployment.
Missing Diagnostic Detail: Are you using opaque tokens (requiring a database lookup/introspection) or self-contained tokens (like JWTs)? The strategy for RS validation differs significantly if the RS is hitting a database versus verifying a cryptographic signature.