IAM
Identity and Access Management resources: roles, policies, users, groups, and identity providers.
API Group:
aws.konfig.io/v1alpha1
IAMRole # ✅ Working
Creates and manages IAM roles including trust policies, permissions boundaries, path, max session duration, and tags. Includes drift detection on the trust policy document.
Spec
| Field | Type | Required | Description |
| roleName | string | ✅ | The name of the IAM role. Immutable after creation. |
| assumeRolePolicyDocument | string | ✅ | JSON trust policy document. Drift detected and re-applied on every sync. |
| description | string | | Human-readable description of the role. |
| maxSessionDuration | int32 | | Maximum session duration in seconds. Range 3600–43200. Default: 3600. |
| path | string | | Path for the role. Default: /. By default the operator only manages roles under /konfig/ path unless overridden in operator config. |
| permissionsBoundary | string | | ARN of the policy to use as a permissions boundary. |
| tags | map[string]string | | AWS tags applied to the role. |
Status
| Field | Description |
| arn | The ARN of the created IAM role. |
| roleId | The stable unique ID of the IAM role (e.g. AROA...). |
| conditions | Standard Kubernetes conditions. Key condition: Ready. |
| observedGeneration | Last reconciled metadata.generation. |
| lastSyncTime | RFC3339 timestamp of the last successful reconciliation. |
Example
apiVersion: aws.konfig.io/v1alpha1
kind: IAMRole
metadata:
name: my-app-role
namespace: my-namespace
spec:
roleName: my-app-role
description: "Role for my application"
maxSessionDuration: 3600
assumeRolePolicyDocument: |
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "pods.eks.amazonaws.com" },
"Action": ["sts:AssumeRole", "sts:TagSession"]
}]
}
tags:
team: platform
env: prod
Notes
roleName is immutable after creation. To rename a role, delete the CR and recreate it.
- Drift detection runs on the trust policy document on every reconcile cycle.
- By default, the operator is configured to only manage IAM roles under the
/konfig/ path. This restriction can be adjusted in the operator's Helm values.
- For EKS Pod Identity, the trust policy must allow
pods.eks.amazonaws.com as the principal with actions sts:AssumeRole and sts:TagSession.
Deletion
Immediate. The controller detaches all managed policies and deletes all inline policies first, then deletes the role. The CR is removed once AWS confirms deletion.
IAMPolicy # ✅ Working
Manages customer-managed IAM policies. Policy document changes create new versions; non-default versions beyond the 5-version limit are automatically deleted.
Spec
| Field | Type | Required | Description |
| policyName | string | ✅ | The name of the IAM policy. Immutable after creation. |
| policyDocument | string | ✅ | JSON policy document. Changes create a new policy version. |
| description | string | | Human-readable description of the policy. Immutable after creation. |
| path | string | | Path for the policy. Default: /. |
| tags | map[string]string | | AWS tags applied to the policy. |
Status
| Field | Description |
| arn | The ARN of the created IAM policy. |
| policyId | The stable unique ID of the IAM policy. |
| defaultVersionId | The currently active policy version ID (e.g. v3). |
| conditions | Standard Kubernetes conditions. Key condition: Ready. |
| observedGeneration | Last reconciled metadata.generation. |
| lastSyncTime | RFC3339 timestamp of the last successful reconciliation. |
Example
apiVersion: aws.konfig.io/v1alpha1
kind: IAMPolicy
metadata:
name: my-app-policy
namespace: my-namespace
spec:
policyName: my-app-policy
description: "Grants S3 read access to my application"
policyDocument: |
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}]
}
tags:
team: platform
Notes
- Changes to
policyDocument create a new version using CreatePolicyVersion with setAsDefault: true.
- IAM allows a maximum of 5 non-deleted versions per policy. Older non-default versions are automatically deleted when the limit is reached.
- For attaching AWS managed policies (e.g.
arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess), use IAMPolicyAttachment with a direct ARN — you do not need to create an IAMPolicy CR for managed policies.
Deletion
Blocked if attached. Deletion fails if the policy is still attached to any role, user, or group. Delete all IAMPolicyAttachment and IAMGroupPolicyAttachment CRs that reference this policy first.
IAMPolicyAttachment # ✅ Working
Attaches a managed IAM policy to an IAM role. Supports referencing other CRs by name or using direct ARNs for AWS managed policies.
Spec
| Field | Type | Required | Description |
| roleRef.name | string | ✅ | Name of the IAMRole CR in the same namespace. Mutually exclusive with roleRef.arn. |
| roleRef.arn | string | | Direct ARN of the IAM role (for roles not managed by this operator). |
| policyRef.name | string | ✅ | Name of the IAMPolicy CR in the same namespace. Mutually exclusive with policyRef.arn. |
| policyRef.arn | string | | Direct ARN of the policy (use for AWS managed policies). |
Status
| Field | Description |
| attached | Boolean indicating whether the policy is currently attached. |
| roleArn | Resolved ARN of the IAM role. |
| policyArn | Resolved ARN of the policy. |
| conditions | Standard Kubernetes conditions. Key condition: Ready. |
| observedGeneration | Last reconciled metadata.generation. |
| lastSyncTime | RFC3339 timestamp of the last successful reconciliation. |
Example — CR Reference
apiVersion: aws.konfig.io/v1alpha1
kind: IAMPolicyAttachment
metadata:
name: my-app-role-policy
namespace: my-namespace
spec:
roleRef:
name: my-app-role # references IAMRole CR
policyRef:
name: my-app-policy # references IAMPolicy CR
Example — AWS Managed Policy
apiVersion: aws.konfig.io/v1alpha1
kind: IAMPolicyAttachment
metadata:
name: my-app-role-s3-readonly
namespace: my-namespace
spec:
roleRef:
name: my-app-role
policyRef:
arn: arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
Notes
- The controller waits for both the role CR and policy CR to be
Ready before attempting the attachment.
- The attachment is verified on every reconcile cycle; if it has been manually removed from AWS, the controller re-attaches it.
- Exactly one of
roleRef.name or roleRef.arn must be specified; same applies to policyRef.
Deletion
Immediate. The policy is detached from the role. The IAMRole and IAMPolicy CRs are not affected.
IAMRolePolicy # ✅ Working
Embeds an inline policy directly on an IAM role. Inline policies are tightly coupled to the role and do not have their own ARN or version history.
Spec
| Field | Type | Required | Description |
| roleRef.name | string | ✅ | Name of the IAMRole CR in the same namespace. |
| roleRef.arn | string | | Direct ARN of the role (alternative to roleRef.name). |
| policyName | string | ✅ | The name of the inline policy (must be unique within the role). |
| policyDocument | string | ✅ | JSON policy document for the inline policy. |
Status
| Field | Description |
| roleArn | The ARN of the IAM role this policy is embedded in. |
| conditions | Standard Kubernetes conditions. |
| observedGeneration | Last reconciled metadata.generation. |
| lastSyncTime | RFC3339 timestamp of the last successful reconciliation. |
Example
apiVersion: aws.konfig.io/v1alpha1
kind: IAMRolePolicy
metadata:
name: my-app-inline-policy
namespace: my-namespace
spec:
roleRef:
name: my-app-role
policyName: AllowDynamoDBAccess
policyDocument: |
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:Query"],
"Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/my-table"
}]
}
Notes
- Prefer
IAMPolicy + IAMPolicyAttachment for policies shared across multiple roles.
- Drift correction is always active — if the inline policy is removed or changed in AWS, the controller re-applies it.
- Inline policies do not count toward the IAM policy version limit.
Deletion
Immediate. The inline policy is removed from the role. The role itself is unaffected.
PodIdentityAssociation # ✅ Working
Links a Kubernetes ServiceAccount to an IAM role via EKS Pod Identity. Optionally annotates the ServiceAccount with the role ARN for compatibility.
Spec
| Field | Type | Required | Description |
| clusterName | string | ✅ | The name of the EKS cluster. |
| targetNamespace | string | ✅ | The Kubernetes namespace of the ServiceAccount. |
| serviceAccountName | string | ✅ | The name of the Kubernetes ServiceAccount. |
| roleRef.name | string | ✅ | Name of the IAMRole CR in the same namespace. |
| roleRef.arn | string | | Direct IAM role ARN (alternative to roleRef.name). |
| annotateServiceAccount | bool | | If true, annotates the ServiceAccount with eks.amazonaws.com/role-arn. Useful for hybrid IRSA/Pod Identity setups. |
| tags | map[string]string | | AWS tags for the association. |
Status
| Field | Description |
| associationId | The unique ID of the EKS Pod Identity association. |
| associationArn | The ARN of the association. |
| roleArn | The resolved IAM role ARN. |
| conditions | Standard Kubernetes conditions. |
| observedGeneration | Last reconciled metadata.generation. |
| lastSyncTime | RFC3339 timestamp of the last successful reconciliation. |
Example
apiVersion: aws.konfig.io/v1alpha1
kind: IAMRole
metadata:
name: my-app-role
namespace: platform
spec:
roleName: my-app-role
assumeRolePolicyDocument: |
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "pods.eks.amazonaws.com" },
"Action": ["sts:AssumeRole", "sts:TagSession"]
}]
}
---
apiVersion: aws.konfig.io/v1alpha1
kind: PodIdentityAssociation
metadata:
name: my-app-pod-identity
namespace: platform
spec:
clusterName: my-eks-cluster
targetNamespace: my-app
serviceAccountName: my-app-sa
roleRef:
name: my-app-role
annotateServiceAccount: true
tags:
team: platform
Notes
- Requires the
eks-pod-identity-agent addon to be installed on the cluster. See EKSAddon.
- Only one association is allowed per (cluster, namespace, serviceAccountName) triple. Creating a second one will fail.
- The IAM role trust policy must allow
pods.eks.amazonaws.com as the principal with both sts:AssumeRole and sts:TagSession actions.
- The
clusterName here refers to the AWS EKS cluster name, not a CR reference.
Deletion
Immediate. The EKS Pod Identity association is deleted. The ServiceAccount and IAM role are unaffected.
IAMUser # ✅ Working
Manages IAM users with path, permissions boundary, and tag sync. Does not manage access keys — create access keys through the AWS console or CLI.
Spec
| Field | Type | Required | Description |
| userName | string | ✅ | The name of the IAM user. Immutable after creation. |
| path | string | | Path for the user. Default: /. |
| permissionsBoundary | string | | ARN of the policy to use as a permissions boundary. |
| tags | map[string]string | | AWS tags applied to the user. |
Status
| Field | Description |
| arn | The ARN of the IAM user. |
| userId | The stable unique ID of the IAM user. |
| conditions | Standard Kubernetes conditions. |
| observedGeneration | Last reconciled metadata.generation. |
| lastSyncTime | RFC3339 timestamp of the last successful reconciliation. |
Example
apiVersion: aws.konfig.io/v1alpha1
kind: IAMUser
metadata:
name: ci-deploy-user
namespace: platform
spec:
userName: ci-deploy-user
path: /automation/
tags:
purpose: ci-cd
team: platform
Notes
userName is immutable after creation.
- Access key management is intentionally out of scope. Use the AWS console, CLI, or a separate automation to create and rotate access keys.
- Use
IAMGroupMembership to add the user to groups, and IAMPolicyAttachment / IAMGroupPolicyAttachment to attach policies.
Deletion
Blocked if in use. Deletion fails if the user has attached policies, group memberships, or existing access keys. Clean these up first.
IAMGroup # ✅ Working
Creates an IAM group. Group membership and policy attachments are managed via IAMGroupMembership and IAMGroupPolicyAttachment CRs.
Spec
| Field | Type | Required | Description |
| groupName | string | ✅ | The name of the IAM group. Immutable after creation. |
| path | string | | Path for the group. Default: /. |
Status
| Field | Description |
| arn | The ARN of the IAM group. |
| groupId | The stable unique ID of the IAM group. |
| conditions | Standard Kubernetes conditions. |
| observedGeneration | Last reconciled generation. |
| lastSyncTime | RFC3339 timestamp of last sync. |
Example
apiVersion: aws.konfig.io/v1alpha1
kind: IAMGroup
metadata:
name: developers-group
namespace: platform
spec:
groupName: developers
path: /teams/
Notes
groupName is immutable after creation.
- Add users to the group with
IAMGroupMembership CRs; attach policies with IAMGroupPolicyAttachment CRs.
Deletion
Blocked if in use. Deletion fails if the group has member users or attached policies. Delete all IAMGroupMembership and IAMGroupPolicyAttachment CRs for this group first.
IAMGroupPolicyAttachment # ✅ Working
Attaches a managed IAM policy to an IAM group. Supports CR references or direct names/ARNs.
Spec
| Field | Type | Required | Description |
| groupRef.name | string | ✅ | Name of the IAMGroup CR in the same namespace. |
| groupRef.groupName | string | | Direct IAM group name (alternative to groupRef.name). |
| policyRef.name | string | ✅ | Name of the IAMPolicy CR in the same namespace. |
| policyRef.arn | string | | Direct policy ARN (use for AWS managed policies). |
Status
| Field | Description |
| attached | Boolean indicating whether the policy is attached. |
| groupName | The resolved IAM group name. |
| policyArn | The resolved policy ARN. |
| conditions | Standard Kubernetes conditions. |
| observedGeneration | Last reconciled generation. |
| lastSyncTime | RFC3339 timestamp of last sync. |
Example
apiVersion: aws.konfig.io/v1alpha1
kind: IAMGroupPolicyAttachment
metadata:
name: developers-s3-policy
namespace: platform
spec:
groupRef:
name: developers-group
policyRef:
arn: arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
Deletion
Immediate. The policy is detached from the group.
IAMGroupMembership # ✅ Working
Adds an IAM user to an IAM group. One CR per user-group relationship.
Spec
| Field | Type | Required | Description |
| groupRef.name | string | ✅ | Name of the IAMGroup CR in the same namespace. |
| groupRef.groupName | string | | Direct IAM group name (alternative to groupRef.name). |
| userRef.name | string | ✅ | Name of the IAMUser CR in the same namespace. |
| userRef.userName | string | | Direct IAM user name (alternative to userRef.name). |
Status
| Field | Description |
| member | Boolean indicating whether the user is currently a member of the group. |
| conditions | Standard Kubernetes conditions. |
| observedGeneration | Last reconciled generation. |
| lastSyncTime | RFC3339 timestamp of last sync. |
Example
apiVersion: aws.konfig.io/v1alpha1
kind: IAMGroupMembership
metadata:
name: alice-developers
namespace: platform
spec:
groupRef:
name: developers-group
userRef:
name: alice-user
Deletion
Immediate. The user is removed from the group. Neither the user nor the group CR is affected.
IAMSAMLProvider # ✅ Working
Creates a SAML identity provider in IAM for federated authentication. The provider name is immutable and forms part of the ARN.
Spec
| Field | Type | Required | Description |
| name | string | ✅ | The name of the SAML provider. Immutable — forms part of the ARN. |
| samlMetadataDocument | string | ✅ | The SAML metadata XML document from your identity provider. Drift detected and updated via UpdateSAMLProvider. |
| tags | map[string]string | | AWS tags applied to the provider. |
Status
| Field | Description |
| arn | The ARN of the SAML provider (e.g. arn:aws:iam::123456789012:saml-provider/MyIdP). |
| validUntil | The expiration date of the SAML metadata, parsed from the XML. |
| conditions | Standard Kubernetes conditions. |
| observedGeneration | Last reconciled generation. |
| lastSyncTime | RFC3339 timestamp of last sync. |
Example
apiVersion: aws.konfig.io/v1alpha1
kind: IAMSAMLProvider
metadata:
name: my-saml-idp
namespace: platform
spec:
name: MyCorpIdP
samlMetadataDocument: |
<?xml version="1.0"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" ...>
<!-- SAML metadata from your IdP -->
</EntityDescriptor>
tags:
idp: okta
Notes
spec.name is immutable after creation — it forms part of the ARN. To rename, delete and recreate.
- Metadata document changes are applied via
UpdateSAMLProvider with drift detection on every reconcile.
Deletion
Immediate. The SAML provider is deleted from IAM.
IAMOIDCProvider # ✅ Working
Creates an OpenID Connect (OIDC) identity provider in IAM for workload identity federation. The URL is immutable; thumbprints and client IDs are mutable with delta sync.
Spec
| Field | Type | Required | Description |
| url | string | ✅ | The HTTPS URL of the OIDC provider (e.g. your EKS cluster OIDC issuer). Immutable after creation. |
| clientIDList | []string | ✅ | List of client IDs (audiences) allowed to authenticate. Delta sync — adds new, removes removed. |
| thumbprintList | []string | ✅ | List of server certificate thumbprints. Delta sync. |
| tags | map[string]string | | AWS tags applied to the provider. |
Status
| Field | Description |
| arn | The ARN of the OIDC provider. |
| conditions | Standard Kubernetes conditions. |
| observedGeneration | Last reconciled generation. |
| lastSyncTime | RFC3339 timestamp of last sync. |
Example
apiVersion: aws.konfig.io/v1alpha1
kind: IAMOIDCProvider
metadata:
name: my-eks-oidc
namespace: platform
spec:
url: https://oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E
clientIDList:
- sts.amazonaws.com
thumbprintList:
- 9e99a48a9960b14926bb7f3b02e22da2b0ab7280
tags:
cluster: my-eks-cluster
Notes
url is immutable after creation. The URL is extracted to form the provider ARN.
thumbprintList and clientIDList support delta sync — the controller adds new entries and removes entries no longer in spec.
- For EKS clusters, the OIDC issuer URL is available in the cluster's status after provisioning. See EKSCluster.
Deletion
Immediate. The OIDC provider is deleted from IAM.