Grants: the CDK's permission sets¶
An opinion layer, less permanent than the rest
Everything on this page is opinion, not fact, and it is the least permanent part of cfn-typed.
| Layer | What it is | How much to rely on it |
|---|---|---|
| Generated resource types | the shapes AWS publishes, regenerated from its schemas | the stable core |
| Permission names | the names of IAM actions, taken from awacs | stable: facts, and mostly additive |
| Grants (this page) | which actions belong together, and on which resources | unstable: a judgement that can change |
A grant can change whenever the AWS CDK changes its mind, can be renamed or removed in any release, and may move to a separate package. If you depend on one, pin the version of cfn-typed, or copy the set you rely on into your own code. The sets are the CDK's opinions, not AWS guidance and not a statement of what is right for your system.
A grant is a named set of IAM actions together with the resources it applies to. It is what the AWS CDK
calls grantRead, grantWrite, grantConsumeMessages and so on, and this layer copies the CDK's decisions
for the major services and says so.
from cfn_typed import grants
grants.Sqs.Queue.consume_messages.on(queue_arn)
grants.S3.Bucket.read.on(bucket_arn, key_arn=my_key)
grants.DynamoDb.Table.read_write_data.on(table_arn, indexes=True)
.on(...) returns a list of statements. Every grant is listed under reference.
What a grant carries¶
- The actions.
Sqs.Queue.consume_messagesis the CDK's set:ReceiveMessage,ChangeMessageVisibility,GetQueueUrl,DeleteMessageandGetQueueAttributes. They are built from the permission names, so a grant cannot contain an action that is not a known name. -
Where they apply. The ARN you pass is expanded the way the CDK does it:
Shape Applies to Example arnthe ARN queues, topics, functions, keys, secrets arn_and_objectsthe ARN and {arn}/{keys}(keysdefaults to*)S3.Bucket.read,write,read_writeobjectsonly {arn}/{keys}S3.Bucket.put,delete,put_aclarn_and_indexesthe ARN, and with indexes=Truealso{arn}/index/*DynamoDB table grants any*; takes no ARNDynamoDb.Table.list_streamsWhen the ARN is an intrinsic such as
get_att("Bucket", "Arn"), the child ARNs are built withFn::Join. 3. Key actions. Passkey_arn=when the resource is encrypted with your own KMS key and you get a second statement allowing the key actions, for examplekms:Decryptfor a read. It is left out when you pass no key, and ignored for grants that need none.
Putting the statements somewhere¶
By default the statements have no Principal: they are identity-policy statements (give principal= for a
resource policy), and a grant knows nothing about where they end up, so there is no side effect on a role as in the CDK:
stmts = [
*grants.Sqs.Queue.consume_messages.on(get_att("OrderQueue", "Arn")),
*grants.DynamoDb.Table.write_data.on(arn.table("orders")),
]
lambda_role("orders-prod", stmts) # inline on a role (the pattern in this book)
iam.managed_policy(PolicyDocument=policy_document(stmts), # or a managed policy
Roles=[ref("WorkerRole")])
The SQS worker example uses exactly this, and its rendered YAML shows the result.
Where they come from¶
They are copied from the AWS CDK (Apache-2.0), at one pinned commit, and the
credit is in the module docstring, in the NOTICE file and here. For services where the CDK keeps a grants.json,
the sets are taken as they are. For the rest (S3, DynamoDB, KMS, Kinesis, Lambda, Secrets Manager) the CDK composes
them in code from constants, and scripts/sync-cdk-grants.py records how, citing the method it read.
The script refuses to emit anything it cannot find in those CDK files, so nothing is typed in from memory. Exact
actions are written as references to the permission names, and a pattern such as s3:GetObject*
is written out as a string, because choosing a pattern is part of the opinion.
No CDK code or documentation text is included. Bumping the pin is a one-line change, followed by a
reviewed diff of the generated module, and, because the example stack's rendered
YAML is committed, by a test failure that shows exactly what changed in the policy.
What it does not do¶
- Choosing for you. The CDK's
addToPrincipalOrResourcedecides between an identity policy and a resource policy by itself. Here you decide: noprincipalgives identity statements, and aprincipalgives resource-policy statements, as described on the policy page. - Service principals as grantees, for example letting S3 invoke a Lambda. That is an
AWS::Lambda::Permissionresource, not a policy statement. - The CDK's other behaviour.
Table.stream_readhere grants the stream actions on the stream ARN; the CDK also grantslist_streams, so use both. S3 uses the non-legacy put actions. Lambdainvokeis on the function ARN; the CDK's version and function-URL variants are not included. - Mutation. Nothing here touches a role. If two resources refer to each other through policies, avoiding the circular dependency is up to how you wire the template.