Business Problem
IDSentinel Solutions' cloud expansion into AWS required establishing a baseline identity architecture before any workloads were deployed. The Security team mandated that no human or service identity operate with standing administrative access — all access must follow least-privilege principles, and any privilege elevation must occur through time-bound role assumption with a full audit trail captured via CloudTrail.
An internal review confirmed that without enforced role assumption boundaries, a compromised service credential would grant unrestricted access to IAM and other AWS services — a direct violation of IDSentinel's Zero Trust initiative.
Risk
- Service identities with standing admin access create permanent blast radius
- No audit trail for privilege elevation without CloudTrail enforcement
- Compromised long-lived credentials grant unrestricted AWS access
- Non-compliant with IDSentinel's Zero Trust and least-privilege mandate
- Potential compliance exposure under SOC 2 Type II CC6.3 controls
Solution Design — 4 Workstreams
IAM Identities
Service user created with programmatic-only access and no inline permissions. All permissions assigned via group membership for consistent policy application.
Least-Privilege Policy
Custom IAM policy with explicit ReadOnly grants and explicit Deny on all IAM write actions — ensuring even a misconfiguration cannot grant write access to the identity plane.
Role Assumption with Trust Boundary
IAM role with scoped trust policy restricting assumption to a single principal with an ExternalId condition — preventing confused deputy attacks.
CloudTrail Audit
Trail enabled across all regions capturing AssumeRole events — tamper-evident audit log for compliance and incident response.
Implementation
-
01
Create IAM Identities
Service user
svc-idsentinel-reportercreated with programmatic-only access (no console login). Added to groupGRP-IAMReporters— policy assigned at group level, not inline, for consistent governance. -
02
Deploy Least-Privilege Policy
Custom policy
IDSentinel-ReadOnly-Policycreated with explicit Allow on IAM read actions and explicit Deny on all IAM write actions. Attached toGRP-IAMReporters— inherited by all group members. Explicit Deny overrides any conflicting Allow — defense in depth. -
03
Create IAM Role with Scoped Trust Policy
Role
Role-IDSentinel-Auditorcreated with trust policy restricting assumption tosvc-idsentinel-reporteronly, enforced by ExternalId conditionIDSentinel-Lab-2026to prevent confused deputy attacks. -
04
Enable CloudTrail
Trail
IDSentinel-AuditTrailcreated across all regions with management events (Read + Write) logged to S3 bucketidsentinel-cloudtrail-logs. -
05
Assume Role via AWS CLI
bash — STS Role Assumption# Verify baseline identity (user, not role) aws sts get-caller-identity --profile idsentinel-reporter # Assume the role with ExternalId condition aws sts assume-role \ --role-arn "arn:aws:iam::ACCOUNT_ID:role/Role-IDSentinel-Auditor" \ --role-session-name "IDSentinel-AuditSession-01" \ --external-id "IDSentinel-Lab-2026" \ --profile idsentinel-reporter # Export temporary credentials export AWS_ACCESS_KEY_ID=<AccessKeyId> export AWS_SECRET_ACCESS_KEY=<SecretAccessKey> export AWS_SESSION_TOKEN=<SessionToken> # Confirm identity is now the ROLE, not the user aws sts get-caller-identity
-
06
Validate Least-Privilege Enforcement
bash — Read/Write enforcement test# Should SUCCEED — allowed by ReadOnly grant aws iam list-users # Should FAIL — blocked by explicit Deny aws iam create-user --user-name test-deny-check # → AccessDenied confirmed ✅
-
07
CloudTrail Audit Evidence
AssumeRole event captured in CloudTrail Event History with full session metadata — principal ARN, session name, ExternalId, source IP, and timestamp — providing complete audit trail for SOC 2 CC6.3 compliance documentation.
Outcome
AccessDenied on iam:CreateUser confirmedImplementation Results
| Metric | Value |
|---|---|
| IAM users created | 1 (programmatic only — no console access) |
| IAM groups created | 1 (GRP-IAMReporters) |
| IAM roles created | 1 (Role-IDSentinel-Auditor) |
| Trust policy scope | Single principal + ExternalId condition |
| Policy type | Custom — explicit Allow + explicit Deny |
| Least-privilege violations tested | 1 (iam:CreateUser → AccessDenied confirmed) |
| Credential type used | Temporary STS credentials (time-bound) |
| Long-lived credentials used | 0 |
| CloudTrail events captured | AssumeRole with full session metadata |
| Permanent admin access granted | 0 |
Files
policies/IDSentinel-ReadOnly-Policy.jsonLeast-privilege IAM policy — ReadOnly grant + explicit Deny on all write actionsdiagrams/aws-iam-flow.pngArchitecture and role assumption flow diagramscreenshots/Evidence across all 7 implementation steps — IAM config, CLI role assumption, Deny enforcement, CloudTrail event