Add activation key encryption - #61
Conversation
…ted union
- Add GET /providers/{provider}/environments/{environment}/activationKeyParameters
- Replace flat ActivationKey with oneOf discriminator (ActivationKeyV1, ActivationKeyV2)
- Add ActivationKeyEncryptedPayload schema for decrypted v2 inner contents
- Add GetActivationKeyParametersResponse with supportedVersions and encryption
- Add EncryptionParameters schema (publicKey, algorithm, keyFormat)
- Read-only endpoint only (no POST/DELETE/PATCH)
73d0574 to
0971219
Compare
| All versions share a common envelope containing `version` and | ||
| `destinationEnvironmentUri`. The remaining fields differ by version. | ||
| type: object | ||
| required: |
There was a problem hiding this comment.
For cleanliness, I'd suggest you just put the properties for version / destinationEnvironmentUri here instead of each oneof reference
properties:
version: ...
destinationEnvironmentUri: ...
oneOf:
- $ref: "$/V1"
- $ref: "$/V2"should work correctly because oneOf refs get merged in at the same depth as where the 'oneOf' is.
There was a problem hiding this comment.
Good call — done in 256c6b4. Hoisted version and destinationEnvironmentUri onto the ActivationKey base as properties alongside the oneOf; the variants now only contribute their variant-specific fields. V1/V2 keep the version enum constraint so the oneOf stays unambiguous.
Confirmed it's valid OpenAPI 3.0 and backward compatible — I validated the base+oneOf structure against a pre-PR v1 key (all fields flat, version: 1), a v2 key, and a negative control (v1 body with version: 2): v1 and v2 both validate, the mismatch is correctly rejected. One note for the future: this relies on NOT setting additionalProperties: false on the base, since the base and the branches are evaluated independently — a base that forbade extras would reject the branch-only fields (encryptedContents, etc.).
| description: |- | ||
| The PEM-encoded public key for encrypting activation key contents | ||
| destined for this environment. Rotated weekly; the environment accepts | ||
| keys encrypted with any of the 4 most recent public keys. |
There was a problem hiding this comment.
Maybe rotation frequency should actually be included as a parameter? Helps inform the caller how often they should be pulling a new key, assuming some providers want more frequent rotations.
There was a problem hiding this comment.
Rather than a frequency parameter, I've added nextRotationAt — a UTC date-time telling the caller approximately when this environment next rotates, so they know precisely how long a fetched key stays usable (better than inferring from a cadence). Made it optional since the receiver accepts any of the 4 most recent keys regardless, so a provider that doesn't publish a schedule isn't forced to. Pushed in 31e0a59.
| publicKey: | ||
| description: |- | ||
| The PEM-encoded public key for encrypting activation key contents | ||
| destined for this environment. Rotated weekly; the environment accepts |
There was a problem hiding this comment.
"Should" be rotated weekly?
Presumably a pair of providers can agree on their frequency based on security needs (either more or less). As part of the spec we recommend at least weekly and matches what we prefer.
There was a problem hiding this comment.
Agreed — softened the wording (31e0a59) to: providers are recommended to rotate at least weekly, but the cadence is ultimately agreed between the two partners based on their security needs. Kept the "accepts any of the 4 most recent keys" line since that's the concrete interop contract.
| $ref: paths/environments.yaml#/OneEnvironment | ||
| /providers/{provider}/environments/{environment}/ConfirmActivationKey: | ||
| $ref: paths/environments.yaml#/ConfirmActivationKey | ||
| /providers/{provider}/environments/{environment}/activationKeyParameters: |
There was a problem hiding this comment.
Any reason to prefer a custom method instead of adding the parameters as attributes on the environment itself?
There was a problem hiding this comment.
Kept it as a separate resource rather than folding onto Environment, for two reasons: (1) Environment is also returned by ListEnvironments, so putting rotating key material on that schema means it either rides along on every list page or needs omit-on-list handling; and (2) the public key + nextRotationAt rotate ~weekly while the rest of Environment is near-static — a dedicated endpoint lets the key material carry its own cache/authz semantics instead of forcing short TTLs on the whole environment read. Both shapes are additive and backward-compatible since this is net-new, so it came down to keeping the rotating bits isolated. Happy to fold it in if you feel the single-call ergonomics outweigh the list/caching coupling.
…ationKey base Address review feedback: declare the shared envelope properties on the ActivationKey base alongside oneOf, instead of repeating destinationEnvironmentUri in each variant. oneOf branches merge at the same depth, so V1/V2 still contribute their variant-specific fields. version retains its per-variant enum constraint in each branch for discrimination. Backward compatible with v1 keys.
…ording - Add optional nextRotationAt (UTC date-time) so callers know when to refetch the public key, instead of exposing a rotation-frequency parameter. - Soften publicKey rotation guidance: recommend at least weekly, but cadence is agreed between the two partners per their security needs.
Adds a required sourceAccountId (originating provider's account on the source CSP) alongside destinationAccountId in the encrypted payload. v2-only: the payload schema is referenced solely by ActivationKeyV2.encryptedContents, so v1 keys are unaffected. Additive since v2 is net-new (no backward-compat impact).
…v2-only-transient)
Adds in a new API to fetch encryption/activation key parameters.
Designs a scheme for encrypted activation key processes.