WAF-SOV-060 โ Privileged Access Controlled (Separation of Duties)
Description
Privileged roles MUST be minimized, time-bound, and subject to regular access reviews. Separation of Duties MUST be enforced: no single principal should be able to create infrastructure, approve deployments, AND manage encryption keys simultaneously. Wildcard IAM permissions ('' on '') are forbidden. Administrative access MUST use JIT (Just-In-Time) provisioning where technically feasible.
Rationale
| Risk | Description |
|---|---|
Risk |
Permanent or far-reaching privileged roles increase insider risk and damage if compromised. |
Risk |
Missing time-boxing for admin access prevents effective least-privilege reviews. |
Requirements
-
Privileged roles MUST be minimized, time-bound, and subject to regular access reviews.
-
Separation of Duties MUST be enforced: no single principal should be able to create infrastructure, approve deployments, AND manage encryption keys simultaneously.
-
Administrative access MUST use JIT (Just-In-Time) provisioning where technically feasible.
Implementation Guidance
-
Document the requirement in a version-controlled policy or standard.
-
Assign ownership and establish a review cadence (e.g., quarterly).
Maturity Levels
| Level | Name | Criteria |
|---|---|---|
L1 |
Ad hoc โ control not consistently applied |
* Manual evidence exists for some workloads, but coverage is unknown. |
L2 |
Standardised โ policy defined and communicated |
* A version-controlled policy, ADR, or standard describes the requirement. |
L3 |
Integrated โ automated validation in CI/CD |
* Terraform checks run automatically on pull requests and report results. |
L4 |
Auditable โ metrics and exceptions tracked |
* Control coverage, failures, and approved exceptions are reported quarterly. |
L5 |
Optimised โ continuous improvement based on data |
* Control effectiveness is measured and iteratively improved. |
Checks
waf-sov-060.tf.aws.no-wildcard-iam-policy
Engine: terraform | Provider: aws | Automated: Yes
IAM policies must not grant Action: with Resource:**
Custom IAM policies must not combine wildcard actions ('') with wildcard resources ('') as this grants full administrative access. This is the most common over-privileged pattern in AWS environments.
Scope: resource โ aws_iam_policy, aws_iam_role_policy, aws_iam_user_policy
Assertions:
* policy json not contains pattern pattern "Action":\\s*\\["\\]]."Resource":\\s*\\["\\]] โ IAM policy grants Action: with Resource:* (full admin). This is forbidden.
Remediation: Replace wildcard Action/Resource combinations with specific permissions and specific resource ARNs following the least-privilege principle.
data "aws_iam_policy_document" "s3_read" {
statement {
effect = "Allow"
actions = ["s3:GetObject", "s3:ListBucket"]
resources = [
aws_s3_bucket.data.arn,
"${aws_s3_bucket.data.arn}/*"
]
}
}
data "aws_iam_policy_document" "admin" {
statement {
effect = "Allow"
actions = ["*"]
resources = ["*"]
}
}
waf-sov-060.tf.aws.no-administrator-access-managed-policy
Engine: terraform | Provider: aws | Automated: Yes
AWS managed AdministratorAccess policy must not be attached to regular roles
The AWS managed policy 'AdministratorAccess' must not be attached to regular IAM roles or users. It is permitted only for explicitly documented break-glass emergency roles.
Scope: resource โ aws_iam_role_policy_attachment, aws_iam_user_policy_attachment, aws_iam_group_policy_attachment
Assertions:
* policy_arn not equals arn:aws:iam::aws:policy/AdministratorAccess โ AdministratorAccess managed policy must not be attached to non-break-glass roles.
Remediation: Replace AdministratorAccess with a custom least-privilege policy. If needed for break-glass, document the use with a comment and restrict activation through JIT/approval workflow.
resource "aws_iam_role_policy_attachment" "app" {
role = aws_iam_role.app.name
policy_arn = aws_iam_policy.app_custom.arn
# Uses a custom least-privilege policy
}
resource "aws_iam_role_policy_attachment" "admin" {
role = aws_iam_role.developer.name
policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess"
}
waf-sov-060.tf.aws.iam-password-policy-configured
Engine: terraform | Provider: aws | Automated: Yes
IAM account password policy must be configured
An aws_iam_account_password_policy resource must exist with minimum password length, complexity requirements, and password reuse prevention.
Scope: resource โ aws_iam_account_password_policy
Assertions:
* minimum_password_length greater than or equal 14 โ IAM password minimum length must be >= 14 characters.
* require_uppercase_characters is true โ IAM password policy must require uppercase characters.
* require_symbols is true โ IAM password policy must require symbols.
* password_reuse_prevention greater than or equal 12 โ IAM password policy must prevent reuse of at least 12 previous passwords.
* max_password_age less than or equal 90 โ IAM password max age must be ⇐ 90 days.
Remediation: Configure an aws_iam_account_password_policy resource with strong password requirements.
resource "aws_iam_account_password_policy" "strict" {
minimum_password_length = 16
require_uppercase_characters = true
require_lowercase_characters = true
require_numbers = true
require_symbols = true
allow_users_to_change_password = true
max_password_age = 90
password_reuse_prevention = 24
}
# No aws_iam_account_password_policy resource defined
waf-sov-060.tf.aws.no-iam-user-direct-access-keys
Engine: terraform | Provider: aws | Automated: Yes
IAM users should not have long-lived access keys in Terraform
Creating aws_iam_access_key resources in Terraform creates long-lived static credentials that should be avoided. Use IAM roles, OIDC federation, or short-lived credentials instead.
Scope: resource โ aws_iam_access_key
Assertions:
* status not equals Active โ Long-lived IAM access keys should not be created via Terraform. Use roles or OIDC.
Remediation: Replace static IAM access keys with IAM roles and temporary credentials. For CI/CD: use OIDC provider to issue short-lived tokens. For applications: use EC2 instance profiles or ECS task roles.
waf-sov-060.tf.stackit.no-wildcard-iam-policy
Engine: terraform | Provider: stackit | Automated: Yes
StackIT IAM policies must not grant wildcard permissions
StackIT IAM policies must not grant wildcard actions and resources. Follow least-privilege principles for sovereign environments.
Scope: resource โ stackit_project
Assertions:
* iam_policy json not contains pattern pattern "\*":\\s*"\\*" โ StackIT IAM policy grants wildcard permissions.
Remediation: Replace wildcard permissions with specific actions and resource ARNs.
# Use specific permissions for StackIT resources
# Wildcard permissions in StackIT IAM policies
waf-sov-060.config.azurerm.privileged-roles-policy
Engine: config | Provider: azurerm | Automated: Yes
Azure privileged role governance policy must be documented
A version-controlled policy document must exist at docs/sovereign/waf-sov-060-azurerm-privileged-roles.md and document the Azure implementation of privileged role minimization, time-bound access (PIM/Entra ID), and regular review.
Scope: file โ docs/sovereign/waf-sov-060-azurerm-privileged-roles.md
Assertions:
* content matches pattern (?i)MUST|SHALL|required|mandatory|enforced|documented โ Azure privileged roles policy file must contain a normative requirement statement.
Remediation: Create or update docs/sovereign/waf-sov-060-azurerm-privileged-roles.md. State the requirement, Azure PIM/Conditional Access configuration, review cadence, and owner.
docs/sovereign/waf-sov-060-azurerm-privileged-roles.md:
- Azure privileged roles are limited to Owner/Contributor only via PIM with time-bound activation.
- Quarterly access reviews are scheduled.
- Break-glass accounts are excluded from PIM and documented.
# docs/sovereign/waf-sov-060-azurerm-privileged-roles.md is missing or does not contain a normative requirement.
waf-sov-060.config.google.privileged-roles-policy
Engine: config | Provider: google | Automated: Yes
GCP privileged role governance policy must be documented
A version-controlled policy document must exist at docs/sovereign/waf-sov-060-google-privileged-roles.md and document the GCP implementation of privileged role minimization, time-bound access, and regular review.
Scope: file โ docs/sovereign/waf-sov-060-google-privileged-roles.md
Assertions:
* content matches pattern (?i)MUST|SHALL|required|mandatory|enforced|documented โ GCP privileged roles policy file must contain a normative requirement statement.
Remediation: Create or update docs/sovereign/waf-sov-060-google-privileged-roles.md. State the requirement, GCP IAM basic-role restrictions, custom roles, review cadence, and owner.
docs/sovereign/waf-sov-060-google-privileged-roles.md:
- GCP basic roles (owner/editor/viewer) are prohibited at project and organization level.
- Custom IAM roles are used with least privilege.
- Quarterly access reviews are scheduled.
# docs/sovereign/waf-sov-060-google-privileged-roles.md is missing or does not contain a normative requirement.
Evidence
| Kind | Required | Description |
|---|---|---|
|
Required |
Terraform configuration implementing the control. |
|
Required |
Policy, ADR, or standard documenting the requirement. |
|
Optional |
Cloud console or API output confirming runtime state. |
Related Controls
| Framework | Controls |
|---|---|
GDPR |
* Art. 32 โ Security of processing (access control) * Art. 5(1)(f) โ Integrity and confidentiality |
BSI C5:2020 |
* IAM-01 โ Identity and access management * IAM-03 โ Privileged access management * IAM-05 โ Separation of duties |
BSI C3A:2026 |
* Dimension 5 โ Operational: EU-based operational personnel * Dimension 5 โ Operational: Separation of duties * Dimension 1 โ Strategic: Effective control |
EUCS (ENISA) |
* IAM-01 โ Access control policy * IAM-03 โ Privileged access |
ISO 27001:2022 |
* A.8.2 โ Privileged access rights * A.8.3 โ Information access restriction * A.5.3 โ Segregation of duties |
SOC 2 Type II |
* CC6.3 โ Role-based access control * CC6.6 โ Logical access |