Hafiz provides multiple layers of access control to secure your data.
All requests must be signed using AWS Signature Version 4:
# AWS CLI handles this automatically
aws --endpoint-url http://localhost:9000 s3 ls
# Or set credentials
export AWS_ACCESS_KEY_ID=your-access-key
export AWS_SECRET_ACCESS_KEY=your-secret-key
Connect to enterprise directory services:
# Configure LDAP
HAFIZ_LDAP_ENABLED=true
HAFIZ_LDAP_URL=ldap://ldap.example.com:389
HAFIZ_LDAP_BASE_DN=dc=example,dc=com
IAM-style policies for fine-grained access control.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowPublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
aws --endpoint-url http://localhost:9000 s3api put-bucket-policy \
--bucket my-bucket \
--policy file://policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::public-bucket/*"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "192.168.1.0/24"
}
}
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::user/readonly"},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}
]
}
| Action | Description |
|---|---|
s3:GetObject |
Download objects |
s3:PutObject |
Upload objects |
s3:DeleteObject |
Delete objects |
s3:ListBucket |
List bucket contents |
s3:GetBucketPolicy |
Read bucket policy |
s3:PutBucketPolicy |
Write bucket policy |
s3:* |
All actions |
| Key | Description |
|---|---|
aws:SourceIp |
Client IP address |
aws:CurrentTime |
Current time |
aws:SecureTransport |
HTTPS required |
s3:prefix |
Object key prefix |
s3:max-keys |
Maximum list results |
Hafiz provides comprehensive IAM-style user management with bucket-level access control.
# Create a basic user
curl -X POST http://localhost:9000/admin/users \
-H "Authorization: Basic $(echo -n 'hafizadmin:secret' | base64)" \
-H "Content-Type: application/json" \
-d '{
"name": "alice",
"email": "alice@example.com",
"description": "Development team member"
}'
Response:
{
"name": "alice",
"access_key": "AKIAXXXXXXXXXXXXXXXX",
"secret_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"email": "alice@example.com",
"description": "Development team member",
"created_at": "2024-01-15T10:00:00Z",
"bucket_access": []
}
Assign users to specific buckets with granular permissions:
| Permission | Allows |
|---|---|
read |
GetObject, ListBucket, HeadObject |
write |
PutObject, DeleteObject |
readwrite |
All read and write operations |
none |
No access (explicit deny) |
curl -X POST http://localhost:9000/admin/users \
-H "Authorization: Basic $(echo -n 'hafizadmin:secret' | base64)" \
-H "Content-Type: application/json" \
-d '{
"name": "app-service",
"description": "Application service account",
"bucket_access": [
{"bucket": "production-data", "permission": "readwrite"},
{"bucket": "logs", "permission": "write"},
{"bucket": "config", "permission": "read"}
]
}'
curl -X PUT http://localhost:9000/admin/users/AKIAXXXXXXXXXXXXXXXX/buckets \
-H "Authorization: Basic $(echo -n 'hafizadmin:secret' | base64)" \
-H "Content-Type: application/json" \
-d '{
"bucket_access": [
{"bucket": "production-data", "permission": "read"},
{"bucket": "backups", "permission": "readwrite"}
]
}'
curl http://localhost:9000/admin/users \
-H "Authorization: Basic $(echo -n 'hafizadmin:secret' | base64)"
Response:
{
"users": [
{
"name": "alice",
"access_key": "AKIAXXXXXXXXXXXXXXXX",
"email": "alice@example.com",
"description": "Development team member",
"enabled": true,
"created_at": "2024-01-15T10:00:00Z",
"bucket_access": [
{"bucket": "dev-bucket", "permission": "readwrite"}
],
"is_admin": false
}
],
"total": 1
}
curl http://localhost:9000/admin/users/AKIAXXXXXXXXXXXXXXXX \
-H "Authorization: Basic $(echo -n 'hafizadmin:secret' | base64)"
# Disable user (revoke all access)
curl -X POST http://localhost:9000/admin/users/AKIAXXXXXXXXXXXXXXXX/disable \
-H "Authorization: Basic $(echo -n 'hafizadmin:secret' | base64)"
# Enable user
curl -X POST http://localhost:9000/admin/users/AKIAXXXXXXXXXXXXXXXX/enable \
-H "Authorization: Basic $(echo -n 'hafizadmin:secret' | base64)"
curl -X POST http://localhost:9000/admin/users/AKIAXXXXXXXXXXXXXXXX/keys \
-H "Authorization: Basic $(echo -n 'hafizadmin:secret' | base64)"
Response:
{
"access_key": "AKIANEWKEYXXXXXXXXX",
"secret_key": "newxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"created_at": "2024-01-15T12:00:00Z"
}
curl -X DELETE http://localhost:9000/admin/users/AKIAXXXXXXXXXXXXXXXX \
-H "Authorization: Basic $(echo -n 'hafizadmin:secret' | base64)"
curl -X POST http://localhost:9000/admin/users \
-H "Authorization: Basic $(echo -n 'hafizadmin:secret' | base64)" \
-H "Content-Type: application/json" \
-d '{
"name": "backup-reader",
"description": "Backup service - read only access to all backups",
"bucket_access": [
{"bucket": "daily-backups", "permission": "read"},
{"bucket": "weekly-backups", "permission": "read"},
{"bucket": "monthly-backups", "permission": "read"}
]
}'
curl -X POST http://localhost:9000/admin/users \
-H "Authorization: Basic $(echo -n 'hafizadmin:secret' | base64)" \
-H "Content-Type: application/json" \
-d '{
"name": "webapp-service",
"description": "Web application service account",
"bucket_access": [
{"bucket": "user-uploads", "permission": "readwrite"},
{"bucket": "static-assets", "permission": "read"},
{"bucket": "temp-files", "permission": "write"}
]
}'
curl -X POST http://localhost:9000/admin/users \
-H "Authorization: Basic $(echo -n 'hafizadmin:secret' | base64)" \
-H "Content-Type: application/json" \
-d '{
"name": "replication-service",
"description": "Internal replication service for DR site",
"bucket_access": [
{"bucket": "production-data", "permission": "write"}
]
}'
Hafiz supports making buckets publicly accessible through bucket policies.
To make a bucket publicly readable:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:hafiz:s3:::my-public-bucket",
"arn:hafiz:s3:::my-public-bucket/*"
]
}
]
}
Hafiz includes a built-in web file browser for non-technical users:
http://your-server:9000/browseAccess public buckets via: http://your-server:9000/browse/bucket-name
Generate time-limited URLs for temporary access without sharing credentials.
# Via Admin API
curl -X GET "http://localhost:9000/api/v1/presigned/download/my-bucket/file.pdf?expires_in=3600" \
-H "Authorization: Bearer $TOKEN"
# Via AWS CLI
aws --endpoint-url http://localhost:9000 s3 presign s3://my-bucket/file.pdf --expires-in 3600
# Via Admin API
curl -X GET "http://localhost:9000/api/v1/presigned/upload/my-bucket/uploads/file.pdf?expires_in=3600" \
-H "Authorization: Bearer $TOKEN"
{
"url": "http://localhost:9000/my-bucket/file.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&...",
"expires_at": "2024-01-15T12:00:00Z",
"bucket": "my-bucket",
"key": "file.pdf"
}