You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Aperio is pure SaaS posture today. The single biggest gap relative to the broader security-posture market is cloud IAM — AWS, Azure, GCP — where the JML / privilege-sprawl / over-permissive-role problems are even more acute than in SaaS, and where every buyer evaluating an SSPM is also asking "do you also do CIEM?"
Adding cloud IAM posture turns Aperio from "SSPM with optional adjacencies" into a unified identity & access posture platform spanning SaaS + cloud. The Person model from #45 already anticipates this: cloud principals are just another SaasIdentity.kind once the model permits it.
Goals
AWS, Azure, GCP IAM connectors that inventory principals, roles, policies, and access grants.
Detection rules for the highest-signal cloud IAM postures (over-permissive roles, dormant access keys, cross-account trust sprawl, public S3 buckets, public storage objects).
Service account w/ workload identity federation or JSON key
iam.googleapis.com for service accounts, cloudresourcemanager.googleapis.com for IAM policies, storage.googleapis.com for bucket ACLs
Each connector ships as a Go package under internal/connectors/<provider>/ mirroring the Google Workspace pattern in internal/bootstrap/google_oauth.go.
Day-one rule pack (cloud IAM)
Rule
Severity
Trigger
aws.public_s3_bucket
CRITICAL
Bucket ACL or policy permits public-read / * principal
aws.iam_user_no_mfa
HIGH
IAM user with console access and no MFA
aws.iam_root_access_key_active
CRITICAL
Root account has an active access key
aws.iam_dormant_access_key
MEDIUM
Access key unused > 90 days
aws.iam_role_admin_policy
HIGH
Role grants AdministratorAccess to wide trust principal
aws.cross_account_trust_external_account
HIGH
Role trust policy permits a principal in an unknown account ID
azure.privileged_role_no_pim
HIGH
Permanent privileged role assignment without PIM eligibility
azure.guest_user_admin_role
CRITICAL
Guest (B2B) user with admin role
azure.app_admin_consent_high_scope
HIGH
App granted admin consent for Mail.Read.All / Sites.FullControl.All (overlaps with M365 #48)
gcp.public_storage_bucket
CRITICAL
allUsers / allAuthenticatedUsers granted on bucket
gcp.service_account_user_managed_key
HIGH
Service account has user-managed keys (vs. workload-identity)
gcp.project_owner_external
HIGH
roles/owner granted to external identity
Cross-cloud Person linkage
When the identity linker (from #45) runs, it also joins:
AWS IAM users to Person.primaryEmail via email tag or username pattern.
Azure AD users to Person.externalEmployeeId (the canonical Entra ID → HRIS bridge).
GCP IAM members to Person.primaryEmail.
Once linked, the /identities/<personId> page from #45 shows cloud access alongside SaaS access — unified. This is the moment Aperio becomes a CIEM.
Remediation actions
Add to remediationActionDefinitions (internal/bootstrap/remediation_actions.go):
Provider
Action
Class
AWS_IAM
aws.disable_access_key
real-provider
AWS_IAM
aws.detach_user_policy
real-provider
AWS_IAM
aws.block_s3_public_access
real-provider
AZURE_AD
azure.revoke_role_assignment
real-provider
AZURE_AD
azure.disable_user
real-provider
GCP_IAM
gcp.remove_iam_binding
real-provider
GCP_IAM
gcp.disable_service_account_key
real-provider
All require AgentProposal.APPROVED.
Phasing
Phase
Scope
P1
AWS IAM connector + top 4 AWS rules (public S3, IAM user no MFA, root access key, dormant access key); CloudFormation template for the read-only role
P2
Azure AD / Entra ID connector + 3 Azure rules; cross-cloud Person linkage in the identity linker
P3
GCP IAM connector + 3 GCP rules
P4
Remediation handlers for all three clouds; CloudTrail/Activity-log ingestion to feed UEBA #12
Open questions
AWS cross-account auth model — managed CloudFormation stack vs. customer-supplied access key? Stack is more user-friendly but couples deploy lifecycle.
Org-level vs. account-level granularity for AWS (does Aperio scan one account or assume role across an entire AWS Org)?
For Azure, MS Graph rate limits are brutal — likely need a separate background-sync cadence.
Public-bucket detection has well-known FP cases (CloudFront origins, intentionally public sites) — should we ship a builtin allowlist pattern?
Problem
Aperio is pure SaaS posture today. The single biggest gap relative to the broader security-posture market is cloud IAM — AWS, Azure, GCP — where the JML / privilege-sprawl / over-permissive-role problems are even more acute than in SaaS, and where every buyer evaluating an SSPM is also asking "do you also do CIEM?"
Adding cloud IAM posture turns Aperio from "SSPM with optional adjacencies" into a unified identity & access posture platform spanning SaaS + cloud. The Person model from #45 already anticipates this: cloud principals are just another
SaasIdentity.kindonce the model permits it.Goals
Personrow (from Identity-first correlation, lifecycle & non-human inventory (ISPM) #45) ties their Okta SSO identity to their AWS IAM principal to their Azure AD object, and we surface the unified access surface.AgentProposalgate (revoke key, detach policy, disable principal).Non-goals
Proposed design
Schema extensions
Add three new providers to the existing
SaaSProviderenum:SaasIdentityalready supportsSERVICE_ACCOUNTkind — no schema change needed for cloud service principals; just emit them with the rightkind.SecurityAsset.typegains:Connector implementations
iam:ListUsers,iam:ListRoles,iam:ListAccessKeys,iam:GetAccountAuthorizationDetails,s3:GetBucketAcl,s3:GetBucketPublicAccessBlock,s3:GetBucketPolicy,sts:GetCallerIdentity, CloudTrail for activity baselines (UEBA #12)Directory.Read.All,RoleManagement.Read.Directory,AuditLog.Read.All)/users,/servicePrincipals,/roleAssignments,/auditLogs/directoryAuditsiam.googleapis.comfor service accounts,cloudresourcemanager.googleapis.comfor IAM policies,storage.googleapis.comfor bucket ACLsEach connector ships as a Go package under
internal/connectors/<provider>/mirroring the Google Workspace pattern ininternal/bootstrap/google_oauth.go.Day-one rule pack (cloud IAM)
aws.public_s3_bucketpublic-read/*principalaws.iam_user_no_mfaaws.iam_root_access_key_activeaws.iam_dormant_access_keyaws.iam_role_admin_policyAdministratorAccessto wide trust principalaws.cross_account_trust_external_accountazure.privileged_role_no_pimazure.guest_user_admin_roleazure.app_admin_consent_high_scopeMail.Read.All/Sites.FullControl.All(overlaps with M365 #48)gcp.public_storage_bucketallUsers/allAuthenticatedUsersgranted on bucketgcp.service_account_user_managed_keygcp.project_owner_externalroles/ownergranted to external identityCross-cloud Person linkage
When the identity linker (from #45) runs, it also joins:
Person.primaryEmailvia email tag or username pattern.Person.externalEmployeeId(the canonical Entra ID → HRIS bridge).Person.primaryEmail.Once linked, the
/identities/<personId>page from #45 shows cloud access alongside SaaS access — unified. This is the moment Aperio becomes a CIEM.Remediation actions
Add to
remediationActionDefinitions(internal/bootstrap/remediation_actions.go):aws.disable_access_keyaws.detach_user_policyaws.block_s3_public_accessazure.revoke_role_assignmentazure.disable_usergcp.remove_iam_bindinggcp.disable_service_account_keyAll require
AgentProposal.APPROVED.Phasing
Open questions
References
IntegrationConnection,SaasIdentity,SecurityAsset,SecurityFinding,AgentProposal, remediation action catalog.