Skip to content

Policies

Audex supports multiple ways to define permissions: inline actions, named profiles, AI-powered intent parsing, and learning from observed API calls.


AWS uses the service:Action format:

Terminal window
# Single action
tryaudex run --allow "s3:GetObject" -- aws s3 ls
# Multiple actions (comma-separated)
tryaudex run --allow "s3:GetObject,s3:ListBucket,s3:HeadObject" -- aws s3 ls
# Wildcards
tryaudex run --allow "s3:*" -- aws s3 ls # All S3 actions
tryaudex run --allow "lambda:Invoke*" -- aws lambda invoke # All Invoke* actions
tryaudex run --allow "*:*" -- aws ec2 describe-instances # All actions (dangerous!)

GCP uses dot-separated permissions like service.resource.verb:

Terminal window
# Single permission
tryaudex run --provider gcp --allow "storage.objects.get" -- gsutil ls
# Multiple permissions
tryaudex run --provider gcp --allow "storage.objects.get,storage.objects.list" -- gsutil ls
# Wildcards
tryaudex run --provider gcp --allow "storage.objects.*" -- gsutil ls
tryaudex run --provider gcp --allow "storage.*.*" -- gsutil ls

Azure uses Microsoft.Service/resource/action format:

Terminal window
# Single action
tryaudex run --provider azure \
--allow "Microsoft.Storage/storageAccounts/read" \
-- az storage account list
# Multiple actions
tryaudex run --provider azure \
--allow "Microsoft.Storage/storageAccounts/read,Microsoft.Storage/storageAccounts/listKeys/action" \
-- az storage account keys list
# Wildcards
tryaudex run --provider azure \
--allow "Microsoft.Storage/storageAccounts/*" \
-- az storage account list

Use --profile instead of manually listing actions:

ProfileActionsUse Case
s3-readonlys3:GetObject,s3:ListBucket,s3:HeadObjectRead S3 objects
s3-readwrites3:GetObject,s3:PutObject,s3:DeleteObject,s3:ListBucketFull S3 access
dynamodb-readonlydynamodb:GetItem,dynamodb:Query,dynamodb:Scan,dynamodb:BatchGetItemRead DynamoDB
dynamodb-readwritedynamodb:GetItem,dynamodb:PutItem,dynamodb:UpdateItem,dynamodb:DeleteItem,dynamodb:Query,dynamodb:ScanFull DynamoDB
lambda-invokelambda:InvokeFunction,lambda:InvokeAsyncInvoke Lambda functions
lambda-deploylambda:UpdateFunctionCode,lambda:GetFunction,lambda:PublishVersionDeploy Lambda
ec2-readonlyec2:DescribeInstances,ec2:DescribeImages,ec2:DescribeSecurityGroupsRead EC2
secrets-readonlysecretsmanager:GetSecretValueRead secrets
iam-readonlyiam:GetUser,iam:ListAccessKeys,iam:GetPolicyRead IAM metadata
ProfilePermissionsUse Case
gcs-readonlystorage.objects.get,storage.objects.listRead Cloud Storage
gcs-readwritestorage.objects.get,storage.objects.list,storage.objects.create,storage.objects.deleteFull Cloud Storage
compute-readonlycompute.instances.list,compute.instances.getRead Compute Engine
bigquery-readonlybigquery.datasets.get,bigquery.tables.get,bigquery.tables.listRead BigQuery
ProfileActionsUse Case
azure-storage-readonlyMicrosoft.Storage/storageAccounts/readRead storage accounts
azure-storage-readwriteMicrosoft.Storage/storageAccounts/read,Microsoft.Storage/storageAccounts/writeFull storage access
azure-keyvault-readonlyMicrosoft.KeyVault/vaults/read,Microsoft.KeyVault/vaults/secrets/readRead Key Vault
azure-compute-readonlyMicrosoft.Compute/virtualMachines/readRead VMs
Terminal window
# Use a built-in profile
tryaudex run --profile s3-readonly -- aws s3 ls
# List all available profiles
tryaudex policies list
# Show details of a profile
tryaudex policies show s3-readonly

Audex supports a cloud-agnostic syntax that translates to provider-specific actions:

UniversalAWSGCPAzure
storage:reads3:GetObject,s3:ListBucketstorage.objects.get,storage.buckets.listMicrosoft.Storage/storageAccounts/read
storage:writes3:PutObject,s3:DeleteObjectstorage.objects.create,storage.objects.deleteMicrosoft.Storage/storageAccounts/write
database:readdynamodb:GetItem,dynamodb:Querybigquery.tables.getMicrosoft.SQL/servers/databases/read
database:writedynamodb:PutItem,dynamodb:UpdateItembigquery.tables.updateMicrosoft.SQL/servers/databases/write
compute:readec2:DescribeInstancescompute.instances.listMicrosoft.Compute/virtualMachines/read
secrets:readsecretsmanager:GetSecretValuesecretmanager.secrets.getMicrosoft.KeyVault/vaults/secrets/read
logs:readlogs:GetLogEventslogging.logEntries.listMicrosoft.Insights/logs/read
monitoring:readcloudwatch:GetMetricStatisticsmonitoring.timeSeries.listMicrosoft.Insights/metrics/read
Terminal window
# AWS: storage:read expands to s3:GetObject,s3:ListBucket
tryaudex run --provider aws --allow "storage:read" -- aws s3 ls
# GCP: storage:read expands to storage.objects.get,storage.buckets.list
tryaudex run --provider gcp --allow "storage:read" -- gsutil ls
# Azure: storage:read expands to Microsoft.Storage/storageAccounts/read
tryaudex run --provider azure --allow "storage:read" -- az storage account list

Automatically discover minimum permissions by observing actual API calls:

Terminal window
# Run a script and observe what permissions it actually uses
tryaudex learn -- ./my-script.sh
# Output:
# Observed actions (from CloudTrail):
# s3:GetObject (2 calls)
# s3:ListBucket (1 call)
# Recommended policy: s3:GetObject,s3:ListBucket
  1. Audex creates a session with broad permissions (you specify a base role)
  2. Your script runs
  3. Audex queries CloudTrail to find all API calls made during the session
  4. Maps CloudTrail event names back to IAM action names
  5. Outputs the minimum set of IAM actions needed
  • CloudTrail has a ~5 minute delay, so this works best for longer-running operations
  • Only works for AWS (GCP/Azure support coming)
  • Requires CloudTrail to be enabled on your account
Terminal window
tryaudex learn --ttl 10m -- python train_model.py
# Waits for script to complete, then queries CloudTrail
# Output shows: dynamodb:Query, s3:GetObject, dynamodb:UpdateItem

Convert a description to IAM permissions using Claude:

Terminal window
# Ask Claude what permissions you need
tryaudex intent "Read from S3 bucket and invoke a Lambda function"
# Output:
# {
# "allow": "s3:GetObject,lambda:InvokeFunction",
# "resource": null,
# "description": "Read objects from S3 and invoke Lambda functions"
# }
# Can include resource restrictions
tryaudex intent "Read only from my-bucket in S3"
# Output:
# {
# "allow": "s3:GetObject",
# "resource": "arn:aws:s3:::my-bucket/*",
# "description": "Read objects from a specific S3 bucket"
# }
  • Set ANTHROPIC_API_KEY environment variable with a valid Claude API key
  • Requires internet access to Anthropic API

Audex sends your natural language description to Claude with a system prompt asking it to extract:

  • The minimum set of IAM actions needed
  • Any resource ARN restrictions
  • A human-readable description

The response is formatted as JSON for easy parsing and use with --allow and --resource.


Define your own reusable policy profiles in ~/.config/audex/profiles.toml:

[profiles.my-data-pipeline]
description = "Read from S3, write to DynamoDB"
actions = "s3:GetObject,dynamodb:PutItem,dynamodb:UpdateItem"
resources = ["arn:aws:s3:::input-data/*", "arn:aws:dynamodb:*:*:table/pipeline-results"]
[profiles.ml-inference]
description = "Invoke SageMaker and read model artifacts"
actions = "sagemaker:InvokeEndpoint,s3:GetObject"
resources = ["arn:aws:s3:::ml-models/*"]

Then use them:

Terminal window
tryaudex run --profile my-data-pipeline -- python pipeline.py
tryaudex run --profile ml-inference -- python inference.py

Prevent certain actions even if the underlying role allows them:

Terminal window
# Global deny list in ~/.config/audex/deny-list.toml
[deny]
actions = [
"iam:*",
"ec2:TerminateInstances",
"rds:DeleteDBInstance",
"s3:DeleteBucket"
]

When you request --allow "s3:*", actions in the deny list are automatically filtered out. Useful for team deployments where you want to prevent accidental destructive operations.


Detect when the actual IAM role permissions have drifted from expected:

Terminal window
# Compare your base role against a known-good policy
tryaudex drift --role-arn arn:aws:iam::123456789012:role/MyRole \
--expected-policy s3-readonly
# Output shows:
# Role has additional permissions not in profile:
# ec2:DescribeInstances
# dynamodb:ListTables
# Consider updating the role or profile definition

Useful for detecting accidental permission creep or infrastructure drift.


Limit credentials to specific resources (AWS only, currently):

Terminal window
# Read-only from a specific bucket
tryaudex run --allow "s3:GetObject,s3:ListBucket" \
--resource "arn:aws:s3:::my-bucket/*,arn:aws:s3:::my-bucket" \
-- aws s3 ls s3://my-bucket/
# Write only to specific DynamoDB table
tryaudex run --allow "dynamodb:PutItem" \
--resource "arn:aws:dynamodb:us-east-1:123456789012:table/my-table" \
-- aws dynamodb put-item --table-name my-table --item '{"id":{"S":"123"}}'

  1. Start with profiles: Use built-in profiles when possible. They’re tested and documented.
  2. Use universal syntax for multi-cloud: If you support multiple clouds, use universal permissions.
  3. Learn first, restrict later: Use tryaudex learn to find actual permissions, then restrict further.
  4. Scope resources: Use --resource to limit to specific buckets, tables, etc. when possible.
  5. Use short, specific actions: Prefer s3:GetObject over s3:* or *:*.
  6. Review deny lists: Ensure critical destructive actions are in your deny list.
  7. Rotate profiles: Periodically check for permission drift and update profiles.