Reference

IAM permissions and conditions

Reference for the ABAC permission model: rule shape, actions, resource patterns, identity templates, condition operators and keys, LIST scoping, and group resolution.

Permission shape

Each IAM user carries one or more permission rules, evaluated per request after SigV4 verification:

{
  "effect": "Allow",
  "actions": ["read", "write", "list"],
  "resources": ["releases/firmware/*"],
  "conditions": {
    "IpAddress": { "aws:SourceIp": "203.0.113.0/24" }
  }
}

effect, actions, and resources are required; conditions is optional.

Effect

ValueMeaning
AllowGrants access when actions, resources, and conditions all match
DenyBlocks access when it matches — overrides every Allow, whether the Deny comes from the user's direct rules or an inherited group

A request with no matching Allow is implicitly denied.

Actions

ActionS3 operations
readGetObject, HeadObject
writePutObject, CopyObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload
deleteDeleteObject, DeleteObjects
listListBuckets, ListObjectsV2, ListMultipartUploads, ListParts
adminCreateBucket, DeleteBucket
*All actions

A user is an admin (admin GUI access, config changes) when at least one Allow rule has actions containing * or admin AND resources containing *.

Resources

Glob patterns matched against bucket/key:

PatternMatches
*Every bucket and key
releasesBucket-level operations only (list, create)
releases/*Every object in releases
releases/firmware/*Objects under the firmware/ prefix
releases/firmware/fw-2.*Glob on the object key

Bucket-level operations match the bare bucket name (no /*); object operations match bucket/*. Full access to one bucket therefore requires both rules:

[
  { "effect": "Allow", "actions": ["*"], "resources": ["releases"] },
  { "effect": "Allow", "actions": ["*"], "resources": ["releases/*"] }
]

Permission templates

Resource strings and string condition values accept identity templates:

TemplateExpands to
${iam:username}The authenticated user's name
${iam:access_key_id}The authenticated user's access key ID

Template facts:

  • The iam: prefix is mandatory; a bare ${username} is rejected. The prefix distinguishes request-time identity substitution from the ${env:NAME} load-time config expansion.
  • Templates are stored raw in the DB/YAML and expanded when the in-memory IAM index is built, after group permissions are merged into each member user.
  • Identity values are percent-encoded before substitution: a username dana/team* becomes dana%2Fteam%2A, so it cannot inject path separators or wildcards.
  • Unknown templates are rejected by user/group API validation and by declarative IAM apply.

Example — a per-user home prefix in db-archive, shared via the Engineering group:

{
  "effect": "Allow",
  "actions": ["read", "write", "list"],
  "resources": ["db-archive/home/${iam:username}/*"]
}

For dana this expands to db-archive/home/dana/*.

Conditions

Conditions within a single rule are ANDed — all must match for the rule to apply. Multiple values for the same key are ORed.

Condition operators

OperatorDescriptionExample
StringEqualsExact string matchs3:prefix = "firmware/"
StringNotEqualsExact string non-matchs3:prefix != "internal/"
StringLikeGlob pattern matchs3:prefix LIKE "home/dana/*"
StringNotLikeGlob pattern non-matchs3:prefix NOT LIKE ".*"
IpAddressCIDR range matchaws:SourceIp in 203.0.113.0/24
NotIpAddressCIDR range non-matchaws:SourceIp NOT in 203.0.113.0/24

Condition keys

KeyTypeAvailable onValue
aws:SourceIpIP address (CIDR)All requestsClient IP — from the direct connection, or from X-Forwarded-For / X-Real-IP when DGP_TRUST_PROXY_HEADERS=true
s3:prefixStringLIST requestsThe prefix query parameter

With DGP_TRUST_PROXY_HEADERS=true on a proxy exposed directly to the internet, clients can spoof aws:SourceIp via a forged X-Forwarded-For header.

s3:prefix string values accept the identity templates above, with the same storage, expansion, and percent-encoding rules as resource patterns.

JSON format

{
  "IpAddress": {
    "aws:SourceIp": ["203.0.113.0/24"]
  },
  "StringNotLike": {
    "s3:prefix": "internal/*"
  }
}

ListBucket prefix scoping

When a user with prefix-scoped permissions (for example { "resources": ["db-archive/home/dana/*"] }) issues a LIST with an empty prefix, or a prefix wider than the policy covers, the proxy admits the request and post-filters the result:

  • Each returned key and CommonPrefix is checked against the user's policy; only keys with read or list permission are returned.
  • Filtered pages carry the response header x-amz-meta-dg-list-filtered: true.
  • is_truncated and the continuation token reflect the engine-level cursor, not the filtered count; the client's max_keys acts as a server-side inspection cap, so a returned page may be smaller than requested.
  • Users whose policy covers the full requested scope receive the engine page unchanged, with no filtering cost.

Workflow-bypass prevention

A PUT to a non-existent bucket returns 404 NoSuchBucket on every backend — including the filesystem backend, where the underlying FS could create the parent directory. Bucket creation requires the admin action; it cannot occur as a side effect of a write.

Canned policy templates

The admin GUI (Access → Users → Apply template) offers four starting-point policies. Generated permissions are editable before saving.

TemplatePermissions
Read-onlyread, list on every resource
Developerread, write, list on every resource
AdminAll actions on every resource
Bucket ownerAll actions on one named bucket (selected on apply)

Group resolution

  • A user's effective permissions are the union of their direct rules and the rules of every group they belong to (for example, dana's direct rules plus the Engineering group's rules).
  • Group permissions are merged into each member at IAM index build time; identity templates expand after this merge.
  • Deny precedence applies across the union: a Deny in any source — direct or inherited — overrides Allows from all sources.
  • OAuth group mapping rules add group memberships on each login; memberships are merged, never replaced, so manual assignments persist.
  • The built-in Administrators group carries { "effect": "Allow", "actions": ["*"], "resources": ["*"] }.