Skip to content

Name the key permissions the Azure walkthrough actually needs - #46

Merged
kirill-abblix merged 3 commits into
masterfrom
docs/azure-key-permissions
Sep 6, 2026
Merged

Name the key permissions the Azure walkthrough actually needs#46
kirill-abblix merged 3 commits into
masterfrom
docs/azure-key-permissions

Conversation

@kirill-abblix

@kirill-abblix kirill-abblix commented Sep 6, 2026

Copy link
Copy Markdown
Member

Driven against a live Key Vault rather than read off the portal.

Signing works with the key permissions get, list and sign. Introspecting an encrypted token then fails with a 403 asking for decrypt: the unwrap goes through Key Vault's decrypt operation, even though the method that performs it is named for unwrapping. So a policy granting unwrapKey and not decrypt issues tokens happily and refuses to read them back, which is a confusing place to land - the failure arrives in a different flow from the grant that caused it.

The page named only the Key Vault Crypto User role. That role covers both operations, so it is correct for a vault on Azure RBAC and no help at all on one still using access policies, where the reader gets a 403 and nothing pointing at which permission is missing. Both cases are named now.

Verified live against Azure Key Vault

With get, list, sign and decrypt granted, the whole custodian-held posture works end to end:

Claim What the run showed
signing happens inside the vault three-part JWS, alg RS256, kid oidc-sign/<version>
the JWKS is public-only n and e present, no private half
the signature verifies with the public key alone verifies from the JWKS; a tampered input is rejected
with encryption on the token is a JWE five parts, RSA-OAEP-256, A256CBC-HS512, kid oidc-enc/<version>
introspection unwraps the CEK through the vault active: true with the expected subject and scope; a corrupted token returns active: false

That also confirms the kid shape the page claims further down: Key Vault publishes <key>/<version> where Transit publishes <key>:<version>.

The posture that mints keys in the process was not exercised against Azure - it needs a storage account for the sealed ring, which this vault has no counterpart for.

Review

Two rounds. The first found that the key-encryption key was told to take the signing key's rights, which include sign, while nothing signs with it at the vault, and that the storage role was scoped to a container the same sentence says does not exist yet. Both are fixed and both were checked against the library source rather than taken on the reviewer's word.

The second returned MERGE and pointed at the same over-grant one paragraph up: the section opened by telling every Azure reader to create the signing and encryption keys, though the minting posture never uses them. The two postures are described separately now.

Every permission claim on the page was read back from the code path that makes the call, and the two Azure role definitions were read back from Azure rather than recalled.

Driven against a live Key Vault: signing works with get, list and sign, and
introspection of an encrypted token then fails with 403 asking for decrypt. The
unwrap goes through Key Vault's decrypt operation despite the method being named
for unwrapping, so a policy that grants unwrapKey and not decrypt issues tokens
and refuses to read them back.

The page named only the Crypto User role, which is right for a vault on Azure RBAC
and no help on one still using access policies - where the reader gets a 403 with
nothing pointing at the permission. Both are named now.
The page told the reader to give the key-encryption key the same rights as the
signing key, which includes sign. Nothing signs with it: the server seals a minted
key by encrypting to that key's public half in process, and the vault sees only
version enumeration and the decrypt that opens a sealed entry. On the one key
whose whole job is protecting other keys, a spare privilege is the wrong place to
be generous, so the set is now get, list and decrypt.

The storage grant was unassignable as written. The same sentence said the
container is created on first use and then told the reader to scope a role
assignment to that container, which cannot exist yet. It is scoped to the storage
account, and the sentence says why.

Also added: creating the keys is a more privileged act than using them, so neither
the permission set named here nor the Crypto User role can do it. Both role
definitions were read back from Azure rather than recalled - Crypto User carries
no create, Crypto Officer carries the whole key namespace.
The section told every Azure reader to create the signing and encryption keys and
grant rights on them, and then described the minting posture as "a little more to
set up". The minting posture does not use those keys at all - the server mints its
own - so a reader following the page for it provisioned two keys nobody reads and
a sign grant nobody exercises. That is the same spare privilege the previous
commit removed from the key-encryption key, one paragraph up, so the two postures
are now described separately and the page says the earlier keys are not used here.

The reason given for scoping the storage role to the account was the weaker of the
two available. Non-existence is not what blocks a container-scoped assignment;
what does is that the identity has to create the container, and an assignment on a
container grants nothing until there is one. The sentence now says that.
@kirill-abblix
kirill-abblix merged commit 826a0f4 into master Sep 6, 2026
2 checks passed
@kirill-abblix
kirill-abblix deleted the docs/azure-key-permissions branch September 6, 2026 17:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant