Access policies
Access policies define what authenticated users can do in S3 Lens — which providers, buckets, prefixes, and actions they may use. Policies compile at startup; changes require a restart.
See Authentication for OIDC setup and identity mapping.
How authorization works
Section titled “How authorization works”When policy.enabled is true (and auth.enabled is true):
- Every API request must include a valid session
- S3 Lens resolves the user’s roles and attached policies from their IdP groups or direct bindings
- The requested operation is checked against allow and deny rules
- Explicit deny beats allow; if nothing matches, access is denied
When policy.enabled is false, authenticated users can perform any action. When auth.enabled is false, all requests are allowed (local development only).
Roles and policies
Section titled “Roles and policies”Roles bundle one or more policies. Users receive roles through auth.bindings or auth.local_users.
policy: enabled: true use_defaults: true policies: uploads-only: allow: - actions: [read, write] resource: { provider: "*", bucket: "*", prefix: "uploads/" }
roles: uploader: policies: [default-viewer, uploads-only]
auth: bindings: - groups: ["team-uploaders"] role: uploaderBuilt-in policy templates
Section titled “Built-in policy templates”When use_defaults: true, S3 Lens provides starter templates:
| Template | Grants |
|---|---|
default-viewer |
Read providers, buckets, and objects |
default-write |
Upload, copy, rename, and create buckets |
default-admin |
All actions |
Reference these in your roles, or define entirely custom policies under policy.policies.
Actions
Section titled “Actions”Each API operation maps to an action. Use these in policy rules:
| Action | What it allows |
|---|---|
providers:read |
List and view configured providers |
buckets:read |
List buckets |
buckets:create |
Create buckets |
buckets:delete |
Delete buckets |
objects:read |
List, download, and bulk download objects |
objects:write |
Upload, copy, and rename objects |
objects:delete |
Delete and bulk-delete objects |
objects:presign |
Generate presigned URLs |
Action aliases
Section titled “Action aliases”In native YAML policies, you can use shorthand aliases:
| Alias | Expands to |
|---|---|
read |
providers:read, buckets:read, objects:read |
write |
objects:write, buckets:create |
delete |
objects:delete, buckets:delete |
admin |
All actions |
Resource patterns
Section titled “Resource patterns”Rules target resources using three dimensions:
resource: provider: "my-garage" # provider name from config, or "*" bucket: "logs" # exact name, wildcard, or "*" prefix: "2024/" # object key prefix, or "*"Examples:
- Read everything on one provider:
{ provider: "garage", bucket: "*", prefix: "*" } - Write only under
uploads/:{ provider: "*", bucket: "*", prefix: "uploads/" } - Full access everywhere:
{ provider: "*", bucket: "*", prefix: "*" }
The provider dimension matches the provider name in your config. It applies to native YAML policies; S3/IAM JSON policies use bucket and prefix from ARNs (see below).
Writing policies
Section titled “Writing policies”Native YAML
Section titled “Native YAML”Define allow and deny rules under policy.policies:
policy: enabled: true use_defaults: true policies: garage-readonly: allow: - actions: [read] resource: { provider: "garage-local", bucket: "*", prefix: "*" }
deny-presign: deny: - actions: ["objects:presign"] resource: { provider: "*", bucket: "*", prefix: "*" }
custom-readonly: allow: - actions: [read] resource: { provider: "*", bucket: "*", prefix: "*" }Attach policies to roles:
roles: garage-reader: policies: [garage-readonly] viewer-no-presign: policies: [default-viewer, deny-presign]S3/IAM JSON policies
Section titled “S3/IAM JSON policies”Reuse existing AWS-style policy documents:
policy: policies: bucket-readonly: s3: file: policies/read-only-bucket.jsonOr inline:
policy: policies: bucket-readonly: s3: inline: | { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": ["s3:GetObject", "s3:ListBucket"], "Resource": [ "arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/*" ] }] }Notes for IAM JSON in S3 Lens:
Principalis ignored — identity comes from OIDC bindings, not the policy document- Standard
ActionandResourcefields are supported Condition,NotAction, andNotResourceare not supported and will be rejected at startups3:ListBucketmatches the bucket ARN (arn:aws:s3:::bucket); object actions matcharn:aws:s3:::bucket/*
Evaluation order
Section titled “Evaluation order”- If
auth.enabledis false → allow all - Resolve the user from their session (subject + groups)
- Collect policies from role and direct bindings
- Match the request against allow and deny rules
- Explicit Deny wins over Allow
- No matching allow → deny
Example scenarios
Section titled “Example scenarios”Read-only viewer
Section titled “Read-only viewer”roles: viewer: policies: [default-viewer]Editor with full write access
Section titled “Editor with full write access”roles: editor: policies: [default-viewer, default-write]Provider-scoped access
Section titled “Provider-scoped access”Limit a team to one backend:
policy: policies: seaweed-only: allow: - actions: [read, write, delete] resource: { provider: "seaweed-local", bucket: "*", prefix: "*" }
roles: seaweed-editor: policies: [default-viewer, seaweed-only]The default-viewer policy lets users see the provider list; seaweed-only restricts mutations to SeaweedFS.
Prefix-scoped uploads
Section titled “Prefix-scoped uploads”policy: policies: uploads-prefix: allow: - actions: [read, write] resource: { provider: "*", bucket: "*", prefix: "uploads/" }Users can list and upload under uploads/ but not modify objects elsewhere.
Deny presigned URLs
Section titled “Deny presigned URLs”policy: policies: deny-presign: deny: - actions: ["objects:presign"] resource: { provider: "*", bucket: "*", prefix: "*" }
roles: viewer-no-presign: policies: [default-viewer, deny-presign]See s3lens.yaml.example for a complete working example with multiple custom policies and roles.