Support specifying tags passed to AssumeRole
bburky opened this issue · 3 comments
An interesting feature to add is allowing specifying the tags used during AssumeRole. AWS allows parameterizing IAM policies based on the role's tags. If it were possible to provide the namespace as a tag, it would allow writing some extremely generic IAM policies parameterized based on namespace.
"Condition": {
"StringEquals": {"aws:ResourceTag/namespace": "${aws:PrincipalTag/namespace}"}
}
One option might be an additional annotation like iam.amazonaws.com/tags
. But I would want a similar permitted
style whitelist to ensure a pod can't request tags I don't want it to have. Maybe allow specifying them at the namespace level?
Disclaimer: I've never actually used these kinds of IAM policies, but it looks like a nice way to write a generic IAM policy that works for multiple namespaces. You could tag your S3 buckets with a namespace tag and kiam could manage access quite easily.
Docs:
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html
https://docs.aws.amazon.com/IAM/latest/UserGuide/access_iam-tags.html
Also, it looks like ${aws:userid}
expands to role-id:caller-specified-role-name
, where "caller-specified-role-name
is specified by the RoleSessionName parameter passed to the AssumeRole request." So it might be already possible to stuff metadata into the session name and parameterize your policy based on ${aws:userid}
.
Related: #38, changes made in support of specifying session-name and external-id should help with implementing this.
I don't have a specific use case for this, but I just realized that it might be possible to write a single generic parameterized IAM policy for multiple namespaces. I think that would be an extremely usable workflow with kiam: make a single IAM policy, and then add tags to resources as appropriate. It would allow individual workloads to own their resources without making tons of Roles.
@bburky I like this! I have been thinking of using ABAC to solve some of our segmentation needs and this feature would work nicely.
I also like the idea of an allow list for the namespace which restricts in our case what tags our tenants can request which further locks things down.
Are you thinking of getting a PR together for this? I am happy to assist or jump in there and get it done if needed. The changes should not be overly complicated because as you mention the work around session-name and external-id opened support for something like this with minimal pain.
I'm likely not going to look at implementing this at the moment. I honestly... haven't actually deployed kiam yet. I was discussing IAM policies with a coworker who uses it on another project and thought of this design.
I'm happy to talk through what the UX is though.
- There are a few weird things like you can have an arbitrary number of key/value tags, how do we fit those into the style of annotations that kaim uses? Maybe create multiple annotations like
iam.amazonaws.com/tag/foo: a
andiam.amazonaws.com/tag/bar: b
to represent this, with those becoming AWS role tags offoo=a
andbar=b
respectively? - Is a whitelist at the namespace level the best design?
- Is limiting the ability to set tags at the namespace level good enough? What are the use cases for setting tags at the Pod level? (This would be easier to implement probably, and lets you set default tags across an entire namespace.)
iam.amazonaws.com/permitted
is a regex, but that doesn't really work here. I think practical usage will want to restrict the tag keys to an exact list, but may also want to restrict values too: only allow a tag ofnamespace=foo
, wherefoo
should not be configurable within the namespace.- Have you considered something like the templating language that CSI drivers use? https://kubernetes-csi.github.io/docs/secrets-and-credentials-storage-class.html
- Hardcoded tags are easy, specify
iam.amazonaws.com/tag/foo: a
at the namespace level - Restricting a key is doable: specify
iam.amazonaws.com/tag/foo: ${pod.annotations['team.example.com/key']}
at the namespace level, thenteam.example.com/key: a
at the pod level. - Doesn't have a nice way to do restrict keys or values to a pattern though. You can't say "values matching this pattern are okay".
- You can force a prefix on a tag though:
iam.amazonaws.com/tag/foo: prefix-${pod.annotations['team.example.com/key']}
.
- You can force a prefix on a tag though:
- Doesn't have a nice way to specify an allowed list of keys at the namespace level, that Pods can optionally apply.
- Hardcoded tags are easy, specify