ARNs and identifiers
Objective
Section titled “Objective”Identifiers are the least reversible decision in the platform. They appear in policies, in metering records, in audit records, in error messages, in customer scripts and in infrastructure state files, from the first request onwards.
Read this page before implementing anything that mints an identifier.
Requirements
Section titled “Requirements”- None
Instructions
Section titled “Instructions”Resource names
Section titled “Resource names”arn:<partition>:<service>:<region>:<account-id>:<resource-type>/<resource-id>arn:aws-shelf:ec2:hel1:123456789012:instance/i-0a1b2c3d4e5f60718arn:aws-shelf:iam::123456789012:user/deployarn:aws-shelf:billing:hel1:123456789012:invoice/2026-000123The region segment is empty for global services. The account segment is present except for resources owned by the platform rather than by a customer.
The partition
Section titled “The partition”PROPOSED: aws-shelf.
The partition cannot be an arbitrary word. The Terraform AWS provider validates
partitions against ^aws(-[a-z]+)*$, and it constructs ARNs itself — in
aws_iam_policy_document, in the aws_arn data source, and in every resource
that synthesises one. A partition outside that pattern is rejected by the
provider, and the ARNs the provider generates would not match ours.
Additionally, and permanently, ARNs arriving with the aws partition are
accepted on input. Terraform derives the partition from provider metadata and
will generate arn:aws: for a region it does not recognise, so a policy written
through it would otherwise never match anything.
This is the least reversible decision in the document set: it is embedded in every stored policy and every Terraform state file the moment a customer writes one.
Resource-type separator
Section titled “Resource-type separator”The separator between resource type and resource id is a slash for every resource type currently defined.
Where a future service mirrors an AWS service that uses the colon form —
resource-type:id — that service documents the colon form for its own
resources. The grammar permits both; the platform does not silently change the
form of an existing resource type.
Account ids
Section titled “Account ids”PROPOSED: twelve decimal digits, never beginning with zero. See Accounts and tenancy.
Infrastructure resource ids
Section titled “Infrastructure resource ids”PROPOSED: a type prefix, a hyphen, and 17 lowercase hexadecimal characters.
i-0a1b2c3d4e5f60718Seventeen hexadecimal characters because that is the modern AWS long-id format,
and because customer tooling validates against it. The Terraform AWS provider,
among others, validates instance ids against ^i-([0-9a-f]{8}|[0-9a-f]{17})$.
Seventeen hex is safe; anything else is not.
| Prefix | Resource |
|---|---|
i- | Instance |
ami- | Image |
vol- | Volume |
snap- | Snapshot |
key- | Key pair |
eni- | Network interface |
sg- | Security group |
vpc- | Network |
subnet- | Subnet |
quo- | Quote |
ord- | Order |
Prefixes for resources that do not exist in v1 are reserved here so that they cannot later be assigned to something else.
These ids are opaque. Customers must not parse them, and nothing in one encodes the account, the region, the creation time, or anything about the hardware.
PROPOSED: ids are generated from a cryptographically secure source, so that one id reveals nothing about the existence, count or ordering of others.
Billing document numbers are different
Section titled “Billing document numbers are different”Invoice numbers are not opaque and not random:
2026-000123They are sequential, gapless within a sequence, and human-readable, because tax authorities require gapless sequential numbering of invoices. An opaque random identifier would not satisfy that.
This is a deliberate exception to the opacity rule rather than an inconsistency, and it applies only to documents that are legal records: invoices and credit notes. Quotes and orders, which are not legal records, use opaque ids.
OPEN (Michael): the exact invoice numbering scheme, and whether the sequence is per-account or global.
Customer-chosen names
Section titled “Customer-chosen names”Where a resource carries a name the customer chooses — a key pair name, a policy name — the constraints are documented on that resource and are never narrowed after release.
PROPOSED: where an AWS counterpart exists, its constraints are adopted exactly. Tooling validates names client-side before calling, so a narrower rule would reject names the client believes are valid, and a wider one would accept names the client refuses to send.
Service names, region names and resource ids are lowercase, and comparison is case-sensitive.
Two exceptions, both real:
- Access key ids are uppercase and case-sensitive. A verifier that lowercases them before lookup breaks every signature.
- HTTP header names are matched case-insensitively by HTTP, and are lowercased only when building the canonical request for a signature.