IAM permissions¶
Every grant the module makes. Checked against main.tf.
Certification primary key policy¶
| Sid | Principal | Actions |
|---|---|---|
EnableAccountRoot |
account root | kms:* |
KeyAdministrators |
key_administrator_arns |
see administrator actions |
AutomationManageKey |
automation_role_arn |
kms:DescribeKey, kms:GetKeyPolicy, kms:GetKeyRotationStatus, kms:ListResourceTags, kms:TagResource, kms:UntagResource, kms:UpdateKeyDescription, kms:PutKeyPolicy |
CertifierSign |
certifier role | kms:Sign |
PublicKeyRead |
certifier and reader roles | kms:GetPublicKey, kms:DescribeKey |
Encryption subkey policy¶
| Sid | Principal | Actions |
|---|---|---|
EnableAccountRoot |
account root | kms:* |
KeyAdministrators |
key_administrator_arns |
see administrator actions |
AutomationManageKey |
automation_role_arn |
as above |
ReaderDeriveSharedSecret |
reader role | kms:DeriveSharedSecret |
PublicKeyRead |
certifier and reader roles | kms:GetPublicKey, kms:DescribeKey |
The two policies are identical except for the sensitive grant: kms:Sign on
the primary, kms:DeriveSharedSecret on the subkey.
Administrator actions¶
Enumerated explicitly rather than by wildcard. Granted unconditionally:
| Group | Actions |
|---|---|
| Read | kms:DescribeKey, kms:GetKeyPolicy, kms:GetKeyRotationStatus, kms:ListResourceTags, kms:ListKeyPolicies, kms:ListGrants |
| Lifecycle | kms:EnableKey, kms:DisableKey, kms:UpdateKeyDescription |
| Aliases | kms:CreateAlias, kms:UpdateAlias, kms:DeleteAlias |
| Tags | kms:TagResource, kms:UntagResource |
| Grants | kms:RevokeGrant |
| Protective | kms:CancelKeyDeletion |
Granted only when allow_administrator_key_deletion = true (default
false):
kms:ScheduleKeyDeletion
Notably absent: kms:PutKeyPolicy, kms:Sign, kms:DeriveSharedSecret,
kms:GetPublicKey.
[!NOTE]
kms:PutKeyPolicyis deliberately not an administrator action. The sibling signing module grantskms:Put*, which includes it — and a wildcard that grants the power to rewrite the grant is not a guardrail. Policy changes flow through the automation role (reviewed plan/apply) or the account root (break-glass), and nowhere else.
What no principal is granted¶
| Principal | Cannot |
|---|---|
automation_role_arn |
kms:Sign, kms:DeriveSharedSecret — a compromised apply runner can neither decrypt nor rebind |
key_administrator_arns |
kms:Sign, kms:DeriveSharedSecret — administering a key is not using it; also kms:PutKeyPolicy, so they cannot widen their own grant |
| reader role | kms:Sign — cannot rebind the certificate |
| certifier role | kms:DeriveSharedSecret — cannot decrypt |
| any OIDC / federated CI identity | anything at all — the module creates no OIDC trust |
Trust policies¶
Both roles use a single statement, AssumeByNamedPrincipals:
| Reader | Certifier | |
|---|---|---|
| Action | sts:AssumeRole |
sts:AssumeRole |
| Principals | reader_principal_arns |
certifier_principal_arns |
| MFA condition | when reader_require_mfa |
when certifier_require_mfa |
| Max session | max_session_duration (default 3600s) |
same |
The MFA condition is Bool: aws:MultiFactorAuthPresent = true. It appears only
in trust policies, never in a key policy — see
roles and trust.
Actions used at runtime¶
| Operation | Call | Role |
|---|---|---|
| Decrypt a message | kms:DeriveSharedSecret (KeyAgreementAlgorithm: ECDH) |
reader |
| Emit the primary key packet | kms:GetPublicKey |
certifier |
| Emit the subkey packet | kms:GetPublicKey on the encryption key |
certifier |
| Sign the subkey binding | kms:Sign |
certifier |
| Check the published cert matches KMS | kms:GetPublicKey on both |
either |