Merged
Conversation
…onment variable to point to server. Add task to manage local kubernetes tests. Update server-config-map, stoke-server-deployment to fix references. Have sqlite database be in memory by default.
… Use local version of container. Update admin interface to try to remove deprecation warning. Add db init config map to helm chart.
…elm values.yaml with new user and group configurations; create .env.production for admin UI
…d introduce Helm chart documentation. Enhance admin UI with base admin path support and fix related capabilities handling. Add integration tests for capabilities endpoint.
…pdate Dockerfile to streamline build steps and adjust paths for assets. Modify .gitignore to exclude new build directories. Introduce base path configuration for improved proxy support and update related API responses. Adjust tests to reflect changes in capabilities and available providers endpoints.
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…umentation - Added Playwright E2E tests in `test/e2e/` to validate admin UI and API against a running Stoke server. - Updated `.tasks.sh` to include an `e2e` subcommand for running Playwright tests. - Enhanced `README.md` and `playwright.md` with instructions on running E2E tests. - Created new test specifications for admin UI and login API. - Documented user stories and test coverage in `test/stories/`. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…@US-010 Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
- Updated `.tasks.sh` to improve E2E test execution, including options for starting/stopping the Stoke server. - Added new configuration files for E2E testing, including `configs/config.yaml` and `dbinit.yaml`. - Enhanced documentation in `playwright.md` to clarify server startup options and test execution. - Updated test specifications to reflect changes in user credentials and navigation elements. - Introduced new helper functions for managing E2E database initialization. Co-authored-by: Cursor <cursoragent@cursor.com>
…Name, etc. Co-authored-by: Cursor <cursoragent@cursor.com>
…Name, etc. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
docs: add High Availability documentation and update README - Removed the High Availability bullet point from the Road Map in README.md. - Added a new document on High Availability detailing requirements, configuration, and behavior for multi-replica setups. - Updated helm/README.md to reference the new High Availability documentation. - Set default replica count in helm/values.yaml to 1 and updated deployment template to use this value. - Enhanced context handling in cluster configuration to ensure proper defaults for refresh intervals.
- Added support for High Availability (HA) in the E2E testing framework, allowing for multiple Stoke replicas to serve a merged JWKS. - Introduced new Docker Compose configurations for HA setups, including two replicas with a shared Postgres database. - Updated the `.tasks.sh` script to include an option for running E2E tests with HA. - Enhanced the configuration structure to support instance IDs for replicas, ensuring unique key IDs in merged JWKS. - Updated documentation to reflect new HA features and usage instructions for E2E tests. - Added tests to verify that tokens issued by one replica can be validated using the merged JWKS from another replica.
Implement HA with federated public key stores.
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.
High availability and federated keystore
Summary
Adds support for running multiple Stoke replicas behind a load balancer with a shared database and federated keystore. When HA is enabled, each replica keeps signing keys in memory only (no key persistence). Peers discover each other via a static list, merge their public keys, and serve a single logical JWKS at
/api/pkeysso tokens issued by any replica can be verified by any replica and by resource servers.Goals
cluster.enabledis true./api/pkeys?local=true, merges with its own keys (deduplicated bykid), and serves the merged JWKS at/api/pkeys. Verification uses this merged set so tokens from any replica are accepted.cluster.refresh_sec, default 30s); updatingstatic_peersand restarting (or config reload) reflects new or removed replicas.Implemented changes
Configuration
internal/cfg/cluster.go– New cluster config:enabled,discovery(e.g."static"),static_peers(base URLs),refresh_sec(default 30),instance_id(optional, for distinctkids in merged JWKS). Cluster is attached to context viaWithContext;ClusterFromContext(ctx)available where the issuer is built.internal/cfg/config.go–Configextended withCluster; cluster wired intoWithContext.internal/cfg/tokens.go– WhenClusterFromContext(ctx).Enabledis true:PersistKeysis forced tofalse, and the issuer is wrapped inkey.NewFederatedTokenIssuer(...)so the token issuer in context is the federated one.Discovery and merge
internal/cluster/discovery.go–Discovererinterface:Peers(ctx) ([]string, error).internal/cluster/static.go–StaticDiscovererimplementingDiscovererfromcluster.static_peers. Tests instatic_test.go.internal/cluster/federated.go–MergeJWKS(localJWKS, peerURLs, httpClient)parses local JWKS, GETs each peer at{base}/api/pkeys?local=true, merges keys bykid, and returns combined JWKSet JSON. Peer fetch failures skip that peer; merge still succeeds. Tests infederated_test.go.Federated issuer
internal/key/federated_issuer.go–FederatedTokenIssuerwraps aTokenIssuer: delegatesIssueToken,RefreshToken,WithContextto inner;PublicKeys(ctx)returns merged JWKS (cached until merged JWKSexpminus a short buffer, orRefreshSec).ParseClaimsuses the merged key set so tokens from any replica are valid. WhenLocalKeysOnly(ctx)is set (e.g. request with?local=true), returns only inner keys to avoid recursion when peers fetch our keys. Tests infederated_issuer_test.go.Web
internal/web/ctx.go– When handling/api/pkeys, requests with?local=truegetkey.WithLocalKeysOnly(ctx)so peer fetches receive only that replica's keys.Helm
helm/values.yaml–server.replicaCount: 1.helm/templates/stoke-server-deployment.yaml–replicas: {{ .Values.server.replicaCount | default 1 }}.helm/README.md– HA section: use shared DB andcluster.enabled+cluster.static_peers; link todocs/high-availability.md.Documentation
docs/high-availability.md– Requirements (shared Postgres/MySQL, no key persistence in HA), how to enable HA (cluster config,static_peers,instance_id), behaviour (issuance, verification, DB), config reference table, and pointer to Helm/values.Testing
test/e2e/specs/ha.spec.ts– E2E:GET /api/pkeysreturns 200 and valid JWKS; with HA profile, replica 2's/api/pkeysreturns merged JWKS with at least two keys. HA run usesdocker-compose.e2e-ha.yamland configsconfig-ha-replica1.yaml/config-ha-replica2.yaml.Configuration example
cluster:
enabled: true
discovery: static
static_peers:
- https://stoke-0:8080
- https://stoke-1:8080
refresh_sec: 30
instance_id: "stoke-0" # optional; keeps kids distinct in merged JWKS