A Study on AWS ABAC
About
It's been a frustrating experience due to a lack of docs and maturity on this technology so here some conclusions from my learnings.
aws:RequestTag
experiment
data "aws_iam_policy_document" "assume-role" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "AWS"
identifiers = [
data.aws_caller_identity.current.account_id
]
}
}
}
data "aws_iam_policy_document" "secretsmanager" {
statement {
actions = ["secretsmanager:CreateSecret", "secretsmanager:TagResource"]
resources = ["*"]
condition {
test = "StringLike"
variable = "aws:RequestTag/Foobar"
values = ["helloworld"]
}
}
}
resource "aws_iam_role" "augustfeng" {
name = "augustfeng"
assume_role_policy = data.aws_iam_policy_document.assume-role.json
inline_policy {
name = "secretsmanager"
policy = data.aws_iam_policy_document.secretsmanager.json
}
}
Given this environment, the aws secretsmanager create-secret --name foobar
will fail because the request needs to include tags.
aws secretsmanager create-secret --name foobar
# An error occurred (AccessDeniedException) when calling the CreateSecret operation: User: arn:aws:sts::123456789012:assumed-role/augustfeng/[email protected] is not authorized to perform: secretsmanager:CreateSecret on resource: foobar because no identity-based policy allows the secretsmanager:CreateSecret actionz
If we include tags, aws secretsmanager create-secret --name foobar --tags
Key=Foobar,Value=helloworld, the request will still fail because there is no
statement to permit tagging.
aws secretsmanager create-secret --name foobar
# An error occurred (AccessDeniedException) when calling the CreateSecret operation: User: arn:aws:sts::123456789012:assumed-role/augustfeng/[email protected] is not authorized to perform: secretsmanager:TagResource on resource: foobar because no identity-based policy allows the secretsmanager:TagResource action
We need to include the secretsmanager:TagResource action for this to work.
+ actions = ["secretsmanager:CreateSecret", "secretsmanager:TagResource"]
- actions = ["secretsmanager:CreateSecret"]
Now able to create a secret only when its tagged with Foobar=helloworld: aws
secretsmanager create-secret --name foobar --tags Key=Foobar,Value=bonjour.
A different tag will not work.
# An error occurred (AccessDeniedException) when calling the CreateSecret operation: User: arn:aws:sts::123456789012:assumed-role/augustfeng/[email protected] is not authorized to perform: secretsmanager:CreateSecret on resource: foobar because no identity-based policy allows the secretsmanager:CreateSecret actionconclusion
This key is pertinent to tagging operations.
aws:ResourceTag
experiments
data "aws_iam_policy_document" "assume-role" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "AWS"
identifiers = [
data.aws_caller_identity.current.account_id
]
}
}
}
data "aws_iam_policy_document" "foo" {
statement {
principals {
type = "AWS"
identifiers = ["arn:aws:sts::654654412147:role/augustfeng"]
}
actions = ["secretsmanager:GetSecretValue"]
resources = ["*"]
condition {
test = "StringLike"
variable = "aws:ResourceTag/Foo"
values = ["helloworld"]
}
}
}
resource "aws_iam_role" "augustfeng" {
name = "augustfeng"
assume_role_policy = data.aws_iam_policy_document.assume-role.json
}
resource "aws_secretsmanager_secret" "foo" {
name = "foo"
tags = {
Foobar = "helloworld"
}
}
resource "aws_secretsmanager_secret_policy" "foo" {
secret_arn = aws_secretsmanager_secret.foo.arn
policy = data.aws_iam_policy_document.foo.json
}In this environment, the augustfeng iam identity does not have permission to get the secret's value in foo.
The resource policy on the secret conditionally grants access to the
augustfeng role, but only if the resource is tagged Foo=helloworld (which it
is not).
If we attach this policy to the augustfeng role, then it will be able to get the secret.
resource "aws_iam_role" "augustfeng" {
name = "augustfeng"
assume_role_policy = data.aws_iam_policy_document.assume-role.json
inline_policy {
name = "foobar"
policy = data.aws_iam_policy_document.foobar.json
}
}conclusion
In the case of a resource policy, the aws:ResourceTag applies to the resource
that where the policy is applied on.
When the policy is applied on an identity, the aws:ResourceTag applies to the
resource that is a target.
aws:PrincipalTag
This key is present when the principal has tags attached to them.
I've encountered two scenarios where this happens:
- When the role has a tag configured.
- When the role is assumed via sts with
-tags.
AWS uses aws:PrincipalTag to implement session tags.
aws:SourceArn
I wanted to configure a resource policy on a secret in Secrets Manager that would allow a specific task to get its value.
This did not work because I don't think ECS exposes task-level ARNs as source.
In fact, the docs (at the time of writing) say it doesn't even support cluster-specific ARNs.
In fact x2, I don't think this would even work because an identity is involved when getting the secrets value and this is for service-to-service calls.