DynamoDB Streams ABAC shipped 19 August 2026 with a 7-day opt-out and a policy trap

Streams ABAC changes what your existing tag conditions mean. The opt-out window is seven calendar days.

Read time
12 min
Word count
2K
Sections
11
FAQs
8
Share
DynamoDB Streams ABAC: seven-day opt-out window, 50 tags per stream, aws:ResourceTag condition key
On this page · 11 sections
  1. What actually changed
  2. The trap: your policies already changed meaning
  3. The condition key that silently fails
  4. CloudFormation will fail before your policies do
  5. What it costs, and what the tags will not tell you
  6. Who is affected, and how to tell if that is you
  7. India-specific considerations
  8. What is still unknown
  9. FAQ
  10. How eCorpIT can help
  11. References

Summary. AWS announced attribute-based access control (ABAC) for Amazon DynamoDB Streams on 19 August 2026, in all commercial AWS Regions and AWS GovCloud (US). You can now attach up to 50 tags to each stream, with a 10 KB ceiling across all tags on that stream, and gate GetRecords, DescribeStream and GetShardIterator on aws:ResourceTag. The part the announcement leaves out matters more: for existing customers the feature is off by default, turning it on is an account-and-Region decision, and you can reverse it only within seven calendar days. Before you enable it, every aws:ResourceTag condition that touches a stream ARN evaluates as though the stream carries no tags at all. On the day you flip it, those same conditions start matching real tags, and both Allow and Deny statements change outcome without anyone editing a policy. The DynamoDB Streams read path itself still bills at $0.0000002 per read request unit beyond the first 2.5 million units a month in US East (N. Virginia), effective 1 August 2026 in the AWS Price List API, and the tags you are about to attach will not split that number for you.

What actually changed

The AWS What's New post frames this as a simplification: fewer IAM policies to manage access across teams and environments. The mechanics in the DynamoDB Developer Guide are narrower than that framing suggests.

Stream resources do not inherit tags from their parent table. You tag the stream ARN directly, in the form arn:aws:dynamodb:*:*:table/*/stream/*, and you manage those tags independently of the table's. Indexes still inherit table tags; streams never did and still do not. So a team that already tags every table with CostCenter and environment starts this migration with zero tagged streams, and any policy written against stream ARNs on the assumption of inheritance will deny.

Three condition keys work, and they are the AWS global keys, not DynamoDB's own: aws:ResourceTag/tag-key, aws:RequestTag/tag-key and aws:TagKeys. They apply to TagResource, UntagResource and to read APIs including GetRecords.

Property DynamoDB tables ABAC DynamoDB Streams ABAC
Tag inheritance Indexes inherit the table's tags Streams inherit nothing from the parent table
Max tags per resource 50 50
Max total tag size 10 KB per table 10 KB per stream
Default state, existing accounts Enabled for most accounts Disabled until you opt in
Enablement scope Per account, per Region Per account, per Region, separate from tables
Self-service opt-out window Seven calendar days Seven calendar days

The last row of that table is the one to write down. Enabling ABAC for tables does not enable it for streams. They are two independent switches, and the Developer Guide states so explicitly.

The trap: your policies already changed meaning

This is the failure mode nobody will find in the announcement. The Developer Guide is blunt about it: "When DynamoDB Streams ABAC is not enabled for your account, aws:ResourceTag conditions are evaluated as if no tags are attached to the stream resource."

Read that twice, then read it once as an Allow and once as a Deny.

As an Allow, a statement permitting GetRecords on arn:aws:dynamodb:*:*:table/*/stream/* when aws:ResourceTag/Team equals Analytics currently denies everything, because no stream ever matches. AWS documents exactly this in Example 1: without Streams ABAC the DescribeStream call returns AccessDeniedException; with it enabled, the same call succeeds. Nothing in the policy changed. The account-level switch did.

As a Deny, the reversal is worse, and it is the one that breaks production. A broad guardrail written against arn:aws:dynamodb:*:*:* with a tag condition has, until now, never matched a stream. After you enable Streams ABAC it starts matching, and consumers that have been reading a stream for two years begin failing with AccessDeniedException. AWS's own pre-flight checklist tells you to hunt for precisely this shape: wildcard resource ARNs carrying tag-based conditions that "might unintentionally apply to streams."

The audit AWS asks for before you enable is three greps across every identity-based policy, resource-based policy and service control policy in the account:

  1. aws:ResourceTag conditions on stream ARNs (table/*/stream/*).
  1. aws:RequestTag or aws:TagKeys conditions paired with dynamodb:TagResource or dynamodb:UntagResource.
  1. Wildcard dynamodb:*:*:* resources with any tag condition attached.

Do it in a non-production account first. The opt-out is seven calendar days, self-service only through the console, and only if you opted in through the console. If Streams ABAC was turned on for your account through AWS Support, the Developer Guide says you cannot reverse it in the console at all — you have to go back to Support.

The condition key that silently fails

DynamoDB has a service-specific dynamodb:ResourceTag condition key. It does not work for streams.

The troubleshooting page documents the exact error: a policy allowing GetRecords with "dynamodb:ResourceTag/Team": "Analytics" fails with AccessDeniedException, because service-specific condition keys "aren't considered as valid condition keys" here. The fix is a one-word edit to aws:ResourceTag/Team. The reason this will bite people is that copy-paste from an existing table policy is the obvious way to write the first stream policy, and the failure looks identical to a missing permission rather than a wrong key.

Two other operational details from the same page. Streams ABAC status updates are asynchronous and tag evaluation is eventually consistent, so a policy that should work may not for a few minutes after you enable. And after a parent table is deleted, the stream lives on for 24 hours; during that window you can still tag or untag it, but only with the CLI or SDK tag-resource, untag-resource and list-tags-of-resource commands against the stream ARN. The console and CloudFormation cannot touch it. Past 24 hours you get ResourceNotFoundException.

CloudFormation will fail before your policies do

For most teams the first symptom will not be an access denial. It will be a red stack.

CloudFormation now propagates stack-level tags to stream resources automatically, in addition to any tags you set explicitly under StreamSpecification.Tags for AWS::DynamoDB::Table or under ReplicaStreamSpecification.Tags for AWS::DynamoDB::GlobalTable. If your deployment role does not hold dynamodb:TagResource and dynamodb:UntagResource on arn:aws:dynamodb:*:*:table/*/stream/*, the deployment fails. This affects stacks that never mention stream tags, because inherited stack tags are enough to trigger the call.

The Developer Guide adds dynamodb:ListTagsOfResource to the list of permissions a CloudFormation service role should carry for stream resources. Add all three in the same change, before you enable ABAC, and roll it through your pipeline as a normal deployment-role update rather than as an emergency fix at 2 a.m.

Teams running scoped, plan-derived deploy permissions will recognise the pattern from IAM policy generation against Terraform plan files: a new resource type appears inside an existing resource's lifecycle, and the least-privilege policy that was correct last month is now short by two actions.

What it costs, and what the tags will not tell you

Here the DynamoDB documentation contradicts itself, and the contradiction has a billing consequence.

The tagging page still carries this note: "Currently, DynamoDB Streams usage cannot be tagged." The ABAC pages, published the same week, describe attaching up to 50 tags to a stream and using them in IAM conditions. Both are true, and reconciling them is the practical point: stream tags exist for authorization, not for cost allocation. Tagging a stream CostCenter: 12345 will gate who can call GetRecords on it. It will not produce a CostCenter line for that stream's usage in Cost Explorer.

That usage is not free. From the AWS Price List API for AmazonDynamoDB in us-east-1, effective 1 August 2026:

Line item Usage type Price
DynamoDB Streams read request units, free tier USE1-Streams-Requests $0.00 for the first 2.5 million per month
DynamoDB Streams read request units, beyond free tier USE1-Streams-Requests $0.0000002 per unit, or $0.20 per million
Change data capture units for Kinesis Data Streams USE1-ChangeDataCaptureUnits-Kinesis $0.10 per million

A Lambda consumer polling a busy stream generates GetRecords calls whether or not records are returned, so the read-request line is driven by poll frequency and shard count as much as by write volume. If your FinOps model assumed stream tags would finally break that number out by team, it will not. The chargeback story still has to be reconstructed from table-level tags and shard topology.

The honest engineering read: this launch is a security control, and treating it as a cost-allocation feature will waste a sprint.

Who is affected, and how to tell if that is you

You are exposed if any of the following is true:

  • You have an AWS account created before 19 August 2026 that uses DynamoDB Streams and any tag-based IAM condition anywhere in its policy set.
  • You run CloudFormation or CDK stacks with stack-level tags that create AWS::DynamoDB::Table or AWS::DynamoDB::GlobalTable resources with streams enabled.
  • You use service control policies with wildcard DynamoDB resources and tag conditions, which will now reach stream ARNs across every account in the organisational unit.
  • You have copied dynamodb:ResourceTag conditions from table policies into anything that touches a stream.

You are not exposed, today, if Streams ABAC is off and you never enable it. Off is not a permanent answer — AWS has enabled table ABAC by default for most accounts, and the same trajectory for streams is the obvious one, but it does buy you the time to run the audit properly.

Checking status is less obvious than it should be. You need dynamodb:GetAbacStatus to read it and dynamodb:UpdateAbacStatus to change it, and the console's "Attribute-based access control for Streams" card appears on the Settings page only if you have a DynamoDB table in the current Region. With no table in the Region, the card's absence tells you nothing. With a table present, no card means enabled. That is a genuinely confusing detection rule, and it is worth scripting GetAbacStatus across every Region rather than clicking through the console.

India-specific considerations

For teams operating under the Digital Personal Data Protection Act 2023, DynamoDB Streams are frequently the path by which personal data leaves the table of record and reaches search indexes, analytics stores and third-party processors. Until now, restricting who could read that flow meant enumerating stream ARNs by name in IAM policies, which does not survive table recreation because the stream ARN carries a timestamp suffix. Tag-based conditions survive it, provided the tag is reapplied at creation, which is exactly what the CloudFormation StreamSpecification.Tags property now does.

That makes Streams ABAC a genuine improvement for purpose-limitation controls, and worth pairing with the wider cloud security posture management sweep most Indian enterprises are already running. The audit work is the same work: find every tag condition, decide what it should mean, then flip the switch.

What is still unknown

Three things the documentation does not settle.

The What's New post says the capability is available in all commercial Regions and GovCloud (US), but AWS does not publish which existing accounts fall into the "most AWS accounts" bucket that gets it enabled by default versus the "existing customers" bucket that does not. There is no documented cutoff date. GetAbacStatus is the only reliable answer.

The Service Authorization Reference page for DynamoDB does not render GetAbacStatus or UpdateAbacStatus without JavaScript, so the canonical action list for these two new IAM actions is currently only readable in the Developer Guide.

And the Tagging.html note that stream usage cannot be tagged has not been updated alongside the ABAC pages. Until AWS reconciles them, assume cost allocation for streams is unchanged.

FAQ

How eCorpIT can help

Auditing an entire policy set for tag conditions that will change meaning is exactly the kind of work that gets deferred until something breaks. Our senior engineering teams run IAM policy audits, deployment-role scoping and CloudFormation remediation as a single piece of work across AWS accounts and Regions, and we are ISO 27001:2022 certified and assessed at CMMI Level 5. If you run DynamoDB Streams in production and want the audit done before the switch is flipped, contact us.

References

  1. Amazon DynamoDB Streams now supports attribute-based access control. AWS What's New, 19 August 2026.
  1. Using attribute-based access control with DynamoDB Streams. Amazon DynamoDB Developer Guide.
  1. Enabling ABAC for DynamoDB Streams. Amazon DynamoDB Developer Guide.
  1. Using ABAC with DynamoDB Streams. Amazon DynamoDB Developer Guide.
  1. Troubleshooting common ABAC errors for DynamoDB Streams. Amazon DynamoDB Developer Guide.
  1. Example 1: Allow stream read access using aws:ResourceTag. Amazon DynamoDB Developer Guide.
  1. Example 2: Allow tagging a stream using aws:RequestTag. Amazon DynamoDB Developer Guide.
  1. Example 4: Tagging streams using CloudFormation. Amazon DynamoDB Developer Guide.
  1. Using attribute-based access control with DynamoDB. Amazon DynamoDB Developer Guide.
  1. Enabling ABAC in DynamoDB. Amazon DynamoDB Developer Guide.
  1. Adding tags and labels to resources in DynamoDB. Amazon DynamoDB Developer Guide.
  1. TagResource API reference. Amazon DynamoDB API Reference.
  1. DescribeStream API reference. Amazon DynamoDB Streams API Reference.
  1. AWS Price List API, AmazonDynamoDB offer, us-east-1. effective 1 August 2026.
  1. Working with DynamoDB Streams. Amazon DynamoDB Developer Guide.

Last updated: 22 August 2026.

Frequently asked

Quick answers.

01 When did AWS ship ABAC for DynamoDB Streams?
AWS announced attribute-based access control for DynamoDB Streams on 19 August 2026. The What's New post states availability in all commercial AWS Regions and in AWS GovCloud (US). Supporting pages in the DynamoDB Developer Guide covering enablement, condition keys, examples and troubleshooting were published alongside the announcement.
02 Is Streams ABAC enabled by default on my account?
It depends on the account. The Developer Guide says Streams ABAC is enabled by default for most AWS accounts, but that existing customers start with it disabled and enable it after auditing their policies. Enabling ABAC for DynamoDB tables does not enable it for streams. The two switches are independent, per account and per Region.
03 How long do I have to reverse the decision?
Seven calendar days from opting in, and only if you opted in yourself through the DynamoDB console Settings page. If Streams ABAC was enabled on your account through AWS Support rather than self-service, the Developer Guide says you cannot disable it in the console and must contact Support to opt out.
04 Why does my stream policy return AccessDeniedException?
The most common cause is using the service-specific dynamodb:ResourceTag condition key, which is not valid for DynamoDB Streams. Replace it with the global aws:ResourceTag key. The other frequent cause is timing: enablement is asynchronous and tag evaluation is eventually consistent, so wait a few minutes and retry the request.
05 Do streams inherit tags from their parent table?
No. Stream resources do not inherit tags from the parent table, and you manage stream tags independently. This differs from indexes, which do inherit the tags applied to their table. You can attach up to 50 tags per stream, with a maximum total size of 10 KB across all tags on that stream.
06 Will CloudFormation deployments break?
They can, and this is usually the first symptom teams see. CloudFormation propagates stack-level tags to stream resources as well as any explicit tags set under StreamSpecification or ReplicaStreamSpecification. If the deployment role lacks dynamodb:TagResource and dynamodb:UntagResource on arn:aws:dynamodb:::table//stream/, the stack fails outright. Add dynamodb:ListTagsOfResource in the same change.
07 Can I use stream tags for cost allocation?
No. The DynamoDB tagging page states that DynamoDB Streams usage cannot be tagged, so stream tags gate authorization rather than splitting the bill. Streams read request units bill at $0.0000002 each beyond the first 2.5 million per month in us-east-1, per the AWS Price List API effective 1 August 2026.
08 How do I check whether Streams ABAC is on?
Call GetAbacStatus, which requires the dynamodb:GetAbacStatus permission and works for any Region. The console alternative is unreliable: the "Attribute-based access control for Streams" card only appears on the Settings page when a DynamoDB table exists in that Region, so its absence does not indicate the status.

About the author

Manu Shukla

Founder & Director

Founder of eCorpIT. Hands-on engineer leading senior-only delivery for AI apps, custom software, and cloud systems for global clients.

Subscribe

One engineering note a week. No fluff, no spam.

Senior-architect playbooks on AI agents, mobile apps, cloud, security, data, and marketing — delivered every Wednesday.

Past the reading

Read enough. Let's build something.

A senior architect responds in 24 working hours with scope, indicative cost, and a timeline. NDA before any technical conversation.