IAM Configuration

Configure users, groups, and policies for S3 authentication and authorization.

Users
Access credentials
Groups
Organize users
Policies
Define permissions
Access Keys
S3 authentication

Overview

ZapFS implements AWS-compatible IAM for S3 authentication and authorization. The Manager cluster serves as the central authority for all IAM state, with metadata services syncing credentials in real-time via gRPC streaming.

Configuration File

IAM is configured via TOML. Create or edit iam.toml:

# iam.toml - ZapFS IAM Configuration

[iam]
# Cache settings
cache_max_items = 1000000
cache_ttl = "5m"

# Optional: Enable STS for temporary credentials
enable_sts = false
sts_default_duration = "1h"
sts_max_duration = "12h"

Defining Users

Users are defined with access keys for S3 authentication. Generate secure keys for production:

# Generate secure keys
openssl rand -hex 10  # access key (20 chars)
openssl rand -hex 20  # secret key (40 chars)
[[iam.users]]
name = "admin"
access_key = "AKIAADMINKEY00001"
secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLE1"
account_id = "000000000001"
display_name = "Admin User"
email = "[email protected]"
disabled = false
policies = ["FullAccess"]

[[iam.users]]
name = "developer"
access_key = "AKIADEVKEY0000002"
secret_key = "devSecretKey1234567890123456789012345678"
account_id = "000000000002"
policies = ["ReadOnly"]
groups = ["developers"]

Defining Groups

Groups let you organize users and attach policies to multiple users at once:

[[iam.groups]]
name = "developers"
policies = ["DevBucketAccess"]

[[iam.groups]]
name = "admins"
policies = ["FullAccess"]

Defining Policies

Policies use AWS IAM policy format. ZapFS supports actions, resources, and conditions:

Full Access Policy

[[iam.policies]]
name = "FullAccess"
document = '''
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "FullAccess",
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": "*"
    }
  ]
}
'''

Read-Only Policy

[[iam.policies]]
name = "ReadOnly"
document = '''
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ReadOnlyAccess",
      "Effect": "Allow",
      "Action": ["s3:Get*", "s3:List*", "s3:Head*"],
      "Resource": "*"
    }
  ]
}
'''

Bucket-Restricted Policy

[[iam.policies]]
name = "DevBucketAccess"
document = '''
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DevBucketFullAccess",
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": ["arn:aws:s3:::dev-*", "arn:aws:s3:::dev-*/*"]
    },
    {
      "Sid": "DenyProductionAccess",
      "Effect": "Deny",
      "Action": "s3:*",
      "Resource": ["arn:aws:s3:::prod-*", "arn:aws:s3:::prod-*/*"]
    }
  ]
}
'''

Supported S3 Actions

ActionDescription
s3:*All S3 operations
s3:GetObjectDownload objects
s3:PutObjectUpload objects
s3:DeleteObjectDelete objects
s3:ListBucketList bucket contents
s3:CreateBucketCreate buckets
s3:DeleteBucketDelete buckets
s3:GetBucketLocationGet bucket region
s3:HeadObjectGet object metadata

Admin API

Manage IAM dynamically via the Manager's Admin HTTP API (default port 8060):

MethodEndpointDescription
POST/v1/iam/usersCreate user
GET/v1/iam/usersList users
DELETE/v1/iam/users/:nameDelete user
POST/v1/iam/users/:name/keysCreate access key
DELETE/v1/iam/users/:name/keys/:keyIdDelete access key
POST/v1/iam/groupsCreate group
POST/v1/iam/groups/:name/membersAdd user to group
POST/v1/iam/policiesCreate policy
POST/v1/iam/users/:name/policiesAttach policy to user

Example: Create a User

curl -X POST http://localhost:8060/v1/iam/users \
  -H "Content-Type: application/json" \
  -d '{
    "name": "newuser",
    "display_name": "New User",
    "email": "[email protected]"
  }'

# Response:
{
  "name": "newuser",
  "access_key": "AKIA...",
  "secret_key": "..."
}

Security Best Practices

  • Generate unique, random access keys and secrets for each user
  • Use groups to organize permissions instead of per-user policies
  • Apply least-privilege: only grant permissions users need
  • Use explicit Deny statements to block sensitive resources
  • Rotate credentials regularly and disable unused accounts
  • Set ZAPFS_IAM_MASTER_KEY for encryption at rest

Master Key Configuration

Secrets are encrypted at rest using AES-256-GCM. Set the master key:

# Generate a 32-byte master key
openssl rand -base64 32

# Set in environment (all services need the same key)
export ZAPFS_IAM_MASTER_KEY="your-base64-encoded-key"

# Or in Docker Compose
environment:
  ZAPFS_IAM_MASTER_KEY: ${ZAPFS_IAM_MASTER_KEY}