The API reference shows the action on each endpoint’s own page, so you do not
have to come back here to look one up. Both come from the same place: the
authorization call in the service, read at build time.
Resource shapes
Ten resource types, and the difference between them decides what a policy can say:
Routes and floating IPs have no name of their own, so they are the two that
cannot be named readably in a policy. Condition on tags for those.
The region slot is populated. A VPC exists in one region, so a policy
written for one region does not reach another — and
crn:network:*:… is how
you write one that spans them deliberately.
The actions
Gateway route collections filter by route-table access. Reading the gateway
alone does not grant access to its routes:
network:ListRoutes is checked
against each table’s CRN and resource tags. Denied tables are omitted before
pagination, and the response includes only visible route-table identities.
Creating is checked against the name you asked for
A create is authorized against the CRN of the resource about to exist, built from the name in the request. So a naming convention is enforceable:team-b-web is denied before anything is written. The request’s
own tags are available as condition context on a create too, via
basalt:RequestTag/<key>, so you can require a team tag in the same statement.
Top-level collections use wildcard permissions
Top-level resource lists are authorized against the collection wildcard — literallycrn:network:<region>:<account>:vpc/*, not against each row. A policy resource
of vpc/prod-* does not match that string, so narrowing a list by name pattern
does not restrict it, it denies it entirely:
So grant the wildcard for listing and scope the operations that act on a
resource. Listing tells a caller that something exists and nothing more.
Sub-resources are governed by their parent — mostly
Security group rules have no CRN of their own. All four rule actions — list, create, get and delete — are checked against the parent group’s CRN with the group’s tags as context. Grantingnetwork:CreateSecurityGroupRule on a
group is therefore exactly as narrow as it reads, and a tag condition on the
group governs who may add rules to it.
Routes are the exception, and the split is worth knowing:
- Checked against the table
- Checked against the route
network:ListRoutes and network:CreateRoute are authorized against the
route table’s CRN and tags. This is what lets you grant “may add routes
to the private table” without granting it on *.A grant to create routes on a table is close to a grant to change where that
table’s subnets send traffic. Someone who can add
0.0.0.0/0 to a private
subnet’s table has made it public — no gateway change and no security-group
change required, because the gateway was already attached.Interface membership is one action, not two
network:SetInterfaceSecurityGroups covers both attaching and detaching,
because the endpoint is a PUT that replaces the whole set. There is no
separate detach action to withhold: whoever can add a group to an interface can
remove every group from it, which leaves that interface dropping all traffic.
Grant it on the interfaces a caller is meant to manage, not on interface/*.
Next
Policies
Document structure, conditions, and how
deny is evaluated.Troubleshooting
What each refusal means, and the order things have to come apart in.