New to Kestra?
Use blueprints to kickstart your first workflows.
Audits AWS IAM user access keys to detect unrotated credentials, enforcing automated key rotation and CIS Benchmark compliance.
Long-lived AWS Identity and Access Management (IAM) access keys are a primary vector for credential theft, unauthorized API access, and cloud infrastructure exfiltration. Security standards such as the CIS AWS Foundations Benchmark, SOC2, and PCI-DSS require organizations to rotate active access keys at least every 90 days and deactivate unused credentials. This sentinel continuously inspects all IAM users and active access keys via the AWS IAM API, tracks key ages and last-used dates against rotation baselines, and alerts Cloud Security teams on Slack with exact deactivation commands.
0 8 * * 1) or triggers on-demand via manual execution.list_users, list_access_keys) to discover all registered IAM accounts and active credentials.get_access_key_last_used to identify credentials exceeding max_key_age_days.io.kestra.plugin.core.flow.If task evaluates whether stale_keys_count exceeds max_tolerated_stale_keys.SlackIncomingWebhook listing usernames, key IDs, ages, and deactivation CLI commands.flowchart TD
A[weekly_iam_key_audit Schedule Trigger] --> B[scan_iam_access_keys Python Script]
B --> C[check_stale_keys Flowable If]
C -- Stale Keys Found --> D[notify_slack_cloudsec Webhook]
C -- All Keys Compliant --> E[log_access_key_audit Log]
D --> E
E --> F[export_access_key_manifest Return]
| Name | Type | Default | Description |
|---|---|---|---|
aws_region |
STRING |
us-east-1 |
Primary AWS region used for IAM API initialization. |
max_key_age_days |
INT |
90 |
Maximum permissible age in days before an active IAM access key is flagged for rotation. |
alert_on_stale_access_keys |
BOOL |
true |
Whether to dispatch alerts when unrotated IAM access keys exceed the maximum age threshold. |
max_tolerated_stale_keys |
INT |
0 |
Maximum permissible stale access key count before triggering an incident notification. |
{{ outputs.scan_iam_access_keys.vars.total_users_audited }}: Total number of IAM user accounts inspected.{{ outputs.scan_iam_access_keys.vars.total_keys_audited }}: Consolidated count of access keys evaluated across all users.{{ outputs.scan_iam_access_keys.vars.stale_keys_count }}: Number of active keys exceeding the rotation age threshold.{{ outputs.scan_iam_access_keys.vars.stale_keys_details }}: Serialized JSON list of stale keys with ages and deactivation CLI commands.{{ outputs.export_access_key_manifest.value }}: Structured dictionary containing the consolidated IAM credential compliance manifest.iam:ListUsers, iam:ListAccessKeys, and iam:GetAccessKeyLastUsed permissions.AWS_ACCESS_KEY_ID: AWS IAM access key ID authorized to audit account IAM credentials.AWS_SECRET_ACCESS_KEY: AWS IAM secret access key.SLACK_WEBHOOK_URL: Slack Incoming Webhook endpoint URL used for sending security alerts.AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and SLACK_WEBHOOK_URL in your Kestra Secret storage.company.security namespace.max_key_age_days according to organizational security policy (e.g., 90 or 60).iam.update_access_key(Status='Inactive') on keys older than 180 days with no activity in 45 days.io.kestra.plugin.core.flow.ForEach loop iterating across AWS accounts via AssumeRole.