-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Epic 5: Licensing Infrastructure
User Story
As a server operator,
I want license keys to be cryptographically signed JWTs verified offline,
So that keys cannot be forged and validation requires no network access.
Acceptance Criteria
Given a valid JWT signed with Ed25519 (EdDSA algorithm)
When JwtLicenseManager.validate(jwt) is called
Then the signature is verified against the embedded public key
And a Right(LicenseKey) is returned with the correct tier, features, quotas, and expiresAt
Given a JWT with an invalid or tampered signature
When JwtLicenseManager.validate(jwt) is called
Then a Left(InvalidLicense("Invalid signature")) is returned
Given a valid JWT that has expired (past exp claim)
When JwtLicenseManager.validate(jwt) is called
Then a Left(ExpiredLicense(expiredAt)) is returned
Given Ed25519 public keys bundled in the JAR (licensing/src/main/resources/keys/)
When a JWT with kid header "softclient4es-2026-03" is validated
Then the matching public key is loaded from the keyring
Given a JWT with an unknown kid header
When JwtLicenseManager.validate(jwt) is called
Then a Left(InvalidLicense("Unknown key ID: ...")) is returned
Given a JWT with tier: "pro", features: ["materialized_views", "jdbc_driver", "flight_sql", "federation"], quotas: { max_clusters: 5, max_result_rows: 100000 }
When the JWT is successfully validated
Then licenseType returns LicenseType.Pro
And hasFeature(Feature.Federation) returns true
And quotas.maxClusters returns Some(5)
Given build dependencies
When sbt "licensing/compile" is run
Then Bouncy Castle (bcprov-jdk18on) and nimbus-jose-jwt are available for Ed25519 verification and JWT parsing
Dependencies
- Feature & Quota Extensions (FR30)
Requirements
- FR22: License key shall be a JWT signed with Ed25519, verified offline using an embedded public key