Agen.co enables organizations to securely expose enterprise context to internal agents, copilots, and AI workflows through an identity-aware control layer that governs access, reduces risk, and centralizes oversight.
A low-code CIAM platform for managing customer identity as you scale.
Empower your workforce with secure agents
AWS attribute-based access control (ABAC) is an IAM authorization strategy that makes access decisions from attributes. In AWS, those attributes are usually tags on a principal, a session, a resource or a request. Tags do not grant access by themselves; an IAM policy must evaluate them.
A common pattern is simple: allow an action when a principal’s access-project tag matches the resource’s access-project tag. Implementing it safely also requires control over where attributes come from, who may change authorization tags, which service actions support each condition key and what happens when a required tag is missing.
access-project
AWS ABAC can replace many resource-specific permissions with a smaller number of reusable policies. Instead of adding every new resource ARN to a project role, you can write a policy that applies whenever trusted principal and resource tags match.
The four building blocks are:
aws:PrincipalTag/key
aws:ResourceTag/key
aws:RequestTag/key
aws:TagKeys
Condition
The AWS IAM ABAC documentation describes the same core model. Two qualifications matter:
ABAC is authorization, not authentication. IAM first has to know which principal is making the request. It then evaluates that principal’s request against the applicable policies.
An AWS ABAC decision begins before IAM evaluates a policy. The value used in the decision has to enter the request context from a trusted source.
access-project=orion
${aws:PrincipalTag/access-project}
The trust boundary starts with this supply chain. If a user can choose their own project tag, or can retag a production resource, a correctly written comparison can still authorize the wrong access.
The final decision also follows the normal IAM policy evaluation logic. Requests start implicitly denied. An applicable allow can grant access, but an explicit deny wins. Service control policies, resource control policies, permissions boundaries and session policies can further limit the effective permission set.
AWS ABAC policies compare attributes in the request context with condition operators. Principal, resource and request tags serve different roles, and their availability must be verified for every service action and resource type.
These global condition keys appear frequently in tag-based policies:
aws:PrincipalTag/access-project
aws:ResourceTag/access-project
aws:RequestTag/access-project
AWS services can also expose service-specific keys such as ec2:ResourceTag/access-project or secretsmanager:ResourceTag/access-project. Do not substitute one form for another by intuition. Check the action and resource type in the AWS Service Authorization Reference.
ec2:ResourceTag/access-project
secretsmanager:ResourceTag/access-project
Use operators that match the key’s data type. Principal, resource and request tag values are single-valued strings in the request context, while aws:TagKeys is multivalued. That is why StringEquals fits a project-tag comparison and ForAllValues:StringEquals can constrain a set of submitted tag keys.
StringEquals
ForAllValues:StringEquals
There is a subtle missing-key trap. AWS documents that ForAllValues can evaluate true when its context key is absent. If a tag must be present, add an explicit Null check rather than assuming the set operator proves presence. The IAM condition-operator reference explains this behavior.
ForAllValues
Null
Treat ABAC as an authorization system, not a collection of independent tags.
Start with attributes that have a clear owner and stable meaning. Examples include project, environment, business unit or data classification. Avoid making a person’s email address or display name the core authorization key; those values are harder to govern and may change for reasons unrelated to access.
For each key, document:
One or two governed attributes are easier to test than a large taxonomy whose combinations no one can enumerate.
List the exact AWS actions and resource types the workload needs. Then check the relevant service page in the Service Authorization Reference for:
Do this before writing the policy. A condition that is unavailable for an action does not become valid because another action in the same service supports it.
For workforce access, AWS IAM Identity Center can pass selected user attributes into AWS accounts as session tags. The values can come from the Identity Center identity store or, with an external identity provider, from SAML assertions.
For direct federation or role assumption, AWS Security Token Service can accept session tags through AssumeRole, AssumeRoleWithSAML and AssumeRoleWithWebIdentity. Workload roles can also carry IAM role tags.
AssumeRole
AssumeRoleWithSAML
AssumeRoleWithWebIdentity
The choice determines who controls the value and when a change becomes effective. Document it as part of the policy, not as an identity-team implementation detail.
Begin with a small action set and one resource type. The following identity-based policy adapts the official AWS Secrets Manager ABAC tutorial into a narrower example. It allows a principal to read and describe Secrets Manager secrets only when both sides have the same non-null access-project value:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "ReadSecretsForMatchingProject", "Effect": "Allow", "Action": [ "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret" ], "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:*", "Condition": { "StringEquals": { "aws:ResourceTag/access-project": "${aws:PrincipalTag/access-project}" }, "Null": { "aws:PrincipalTag/access-project": "false", "aws:ResourceTag/access-project": "false" } } } ] }
Replace the placeholders with your Region and account ID. The example intentionally omits ListSecrets, so it will not power a secret-list workflow. List actions require a separate design review because they do not behave like access to one tagged resource; do not silently add a broad list allow. The example also avoids secretsmanager:*; a policy that automatically inherits every future service action is difficult to call least privilege.
ListSecrets
secretsmanager:*
The policy uses a principal tag as a policy variable. IAM substitutes the caller’s value into the string comparison. The Null conditions make the intended fail-closed behavior explicit when either required tag is absent.
If a secret uses a customer-managed KMS key, this Secrets Manager policy is not sufficient by itself. GetSecretValue also requires separately scoped kms:Decrypt permission. Creating a secret with a customer-managed key requires kms:GenerateDataKey and kms:Decrypt; keep those KMS permissions in a separately reviewed statement. AWS documents these requirements in Secrets Manager encryption and key permissions.
GetSecretValue
kms:Decrypt
kms:GenerateDataKey
Reading matching resources is only half of the design. If creators can omit or invent the authorization tag, resources can become inaccessible or land in the wrong access domain.
This separate statement allows a principal to create a Secrets Manager secret with tags only when the submitted project tag matches the principal’s project. The Secrets Manager CreateSecret API requires secretsmanager:TagResource permission when the request includes tags, so both actions appear here. The statement permits only the required key plus an optional Name key:
secretsmanager:TagResource
Name
{ "Version": "2012-10-17", "Statement": [ { "Sid": "CreateSecretForOwnProject", "Effect": "Allow", "Action": [ "secretsmanager:CreateSecret", "secretsmanager:TagResource" ], "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:*", "Condition": { "StringEquals": { "aws:RequestTag/access-project": "${aws:PrincipalTag/access-project}" }, "ForAllValues:StringEquals": { "aws:TagKeys": [ "access-project", "Name" ] }, "Null": { "aws:PrincipalTag/access-project": "false", "aws:RequestTag/access-project": "false" } } } ] }
ForAllValues:StringEquals limits the submitted keys; it does not prove that access-project was supplied. The Null check provides that presence requirement.
Do not treat this as a complete production mutation policy. Because the statement grants TagResource, it can also match a later standalone request that retags a secret to the caller’s project. Any other policy that grants TagResource or UntagResource can create the same bypass. Put creation behind a dedicated provisioning role or workflow, and separately prevent ordinary principals from changing or removing protected authorization tags. AWS publishes an SCP pattern for protecting authorization tags; adapt and test it against your administrative model rather than copying it blindly.
TagResource
UntagResource
AWS Organizations tag policies can standardize allowed keys and values. Basic compliance enforcement does not require a missing tag on every direct resource-creation path, while required-tag-key enforcement applies only to supported infrastructure-as-code workflows. Use an SCP or another tested provisioning control for direct API guardrails. AWS documents these tag-policy enforcement boundaries.
A principal tag may come from an IAM user or role tag, or from a session tag attached to temporary credentials. Session tags are useful when a directory owns workforce attributes, but they add trust-policy and lifecycle requirements.
AWS STS requires the role trust policy to permit sts:TagSession when a caller passes session tags. AWS lets you pass up to 50 session tags, with one value per tag. Session tags apply only to the current session, and they continue through role chaining only when the keys are marked transitive. A new session tag overrides a role tag with the same key regardless of character case. These details are documented in Pass session tags in AWS STS.
sts:TagSession
For IAM Identity Center, decide whether each access-control value comes from the Identity Center identity store or directly from the external IdP’s SAML assertion. If the same attribute is configured in Identity Center and supplied in SAML, the configured identity-store mapping takes precedence. That precedence can explain a correct-looking IdP value that never appears in the AWS session.
Newly issued role sessions pick up changed session attributes; existing temporary credentials retain the attributes with which they were issued until the session expires. IAM Identity Center provides a procedure for responding to active AWS account sessions, including an SCP deny step that blocks use of role sessions that can remain active for up to the configured maximum. Include session duration, reauthentication, immediate-deny handling and role chaining in the change-propagation design, especially for project transfers and departures.
Do not ship an ABAC policy after proving only that the happy path works. Create at least two principals and two resources with different project values, then record the expected decision for each case.
orion
atlas
Use IAM Access Analyzer policy validation to catch syntax, action, ARN and condition-key findings. Use the IAM policy simulator for fast decision checks with explicit context values, but then test in a non-production AWS account. The simulator does not verify that a service action actually supports every supplied global condition key, and it does not evaluate resource control policies. Its result can therefore differ from a live request.
The final test should include the whole effective policy set: identity policies, resource policies, permissions boundaries, session policies and relevant AWS Organizations controls. A matching ABAC statement may still return an overall deny, while a separate broad allow may make a test pass for the wrong reason.
AWS ABAC failures usually come from the attribute supply chain, unsupported condition keys, session behavior or another policy layer—not from the tag comparison alone. Start with the caller’s actual session and the target resource instead of the intended directory state.
When troubleshooting, inspect the actual caller session rather than the intended directory record. Then examine the resource tags, the action’s supported condition keys and every policy layer that contributes to the result. CloudTrail can show the principal/session context and the request that occurred; it does not by itself prove that your policy design covers every denied case.
AWS RBAC assigns permissions through roles and policies; AWS ABAC adds conditions that select resources from trusted attributes. Use RBAC for stable action sets, ABAC for repeated resource boundaries, and a hybrid when roles should define operations while tags limit their scope.
AWS ABAC and RBAC solve different administration problems and are commonly combined.
For example, a Developer role can define the permitted EC2 actions while Project=Orion limits those actions to Orion resources. The role answers “which operations?” and the tag condition answers “on which resources?”
Developer
Project=Orion
ABAC is not automatically more secure or simpler. It reduces policy duplication only when the attribute model is smaller, clearer and better governed than the permissions it replaces. For a broader model-selection framework, see RBAC vs ABAC: differences and when to use each.
aws:RequestTag
AWS IAM ABAC protects AWS actions and resources. Your SaaS application still needs its own authorization decision for questions such as whether a user in Tenant A may read Invoice B, edit a workspace or list customer records.
It is possible to include a trusted tenant identifier in an AWS principal tag and use IAM to isolate tenant-partitioned resources. AWS publishes a SaaS tenant-isolation example using ABAC and IAM. But a tag comparison does not automatically validate application membership, active tenant context, resource ownership or list filtering. Those controls still need an explicit design.
The two layers can use related attributes, but they answer different questions:
These are related authorization layers, not the same decision. The application must preserve tenant context when it translates a product request into an AWS request.
See the authorization architecture guide for the application decision model and the general ABAC guide for subject, resource, action and environment attributes outside AWS. Frontegg’s Authorization and Entitlements is the product route for customer-facing application access control; it does not replace AWS IAM policy design.
Before rollout, verify that:
Record where every decision attribute came from, who can change it, which AWS operations honor it and which denied tests prove the boundary before treating the policy as ready for production.