Docs

Permissions

Alien derives three layers of permissions from your stack definition:

  1. Provisioning — Creates resources during initial setup. The customer's admin runs this once. Alien never holds these.
  2. Management — What Alien uses to reconcile deployments. Live resources receive ongoing provisioning permissions; frozen resources remain owned by setup. Optional features can add narrower permissions for health checks, telemetry, Commands, or Remote Bindings.
  3. Application runtime — What your deployed code can access. Controlled by permission profiles. This page covers this layer.

Resources are isolated by default. A worker can't read from storage, write to a queue, or access a vault unless you explicitly grant it access. This is enforced at the cloud level — IAM policies on AWS, service account bindings on GCP, role assignments on Azure.

Permission Profiles

A permission profile defines what a worker can access. Define them in your stack:

export default new alien.Stack("my-app")
  .add(data, "frozen")
  .add(cache, "frozen")
  .add(api, "live")
  .permissions({
    profiles: {
      execution: {
        data: ["storage/data-read", "storage/data-write"],
        cache: ["kv/data-read", "kv/data-write"],
      },
    },
  })
  .build()

Then assign it to a worker:

const api = new alien.Worker("api")
  .permissions("execution")
  .build()

Under the hood, each profile becomes a cloud identity:

  • AWS: IAM Role
  • GCP: Service Account
  • Azure: User-assigned Managed Identity

Scopes

The keys inside a profile control the scope:

profiles: {
  execution: {
    "*": ["storage/data-read"],           // all storage in the stack
    "logs-storage": ["storage/data-write"] // only this specific bucket
  }
}
  • "*"stack-level: applies to all resources of that type with the stack prefix
  • "resource-name"resource-scoped: applies to only that specific resource

Permission Sets

Permission sets are named bundles of cloud permissions that work across all platforms:

ResourceAvailable Sets
Storagedata-read, data-write
KVdata-read, data-write
Queuedata-read, data-write
Vaultdata-read, data-write
Workerexecute, invoke
AIinvoke
Postgresdata-access
Emailsend, manage-identities

Each set maps to specific cloud actions. For example, storage/data-read translates to:

  • AWS: s3:GetObject, s3:GetObjectVersion, s3:ListBucket
  • GCP: storage.objects.get, storage.objects.list, storage.buckets.get
  • Azure: Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read

You don't need to know the cloud-specific actions — Alien handles the translation.

How It Works

When you deploy, Alien:

  1. Creates a cloud identity for each profile (IAM Role, Service Account, Managed Identity)
  2. Generates a permission policy from the declared permission sets
  3. Attaches the policy to the identity
  4. Configures workers to run with that identity

For resource-scoped permissions, each resource controller applies additional policies after the resource is created — scoped to the exact resource ARN, GCS bucket, or Azure resource ID.

Least-Privilege by Default

Nothing is granted unless declared. A worker with the execution profile can only do what the profile explicitly allows. If you don't grant storage/data-write, writes will fail with a permission error at runtime.

This matters especially when deploying to customer environments. The customer's security team can audit exactly what your software is allowed to do — and verify it matches what you've declared.

The same least-privilege principle applies to management permissions. Alien auto-derives provisioning permissions for live resources, including the actions required to create, update, replace, or remove them. Frozen resources do not receive those permissions. Health checks, telemetry, Commands, and other enabled features are derived separately and may add narrower access to a specific resource.

Build management can read build metadata such as build status and history. Log and artifact access is modeled separately through explicit build log/artifact permissions.

Sensitive management access must be explicit. Some grants are written by preflights: Alien creates one internal vault named secrets for deployment secret environment variables, and the secrets preflight adds vault/data-read / vault/data-write on that concrete vault so deployment secrets can be synced. When commands are enabled, the commands preflight adds worker/dispatch-command on the concrete worker. User-declared vaults remain customer-managed unless you opt in:

.permissions({
  management: {
    extend: {
      "customer-secrets": ["vault/data-write"],
    },
  },
})

Grant vault/data-read only when the management identity must read secret values. Grant vault/data-write only when it must write secret values. On GCP, Alien generates custom IAM roles from the exact permissions declared in the permission sets, so the resulting roles and any IAM Conditions are visible in the reviewed role plan.

Custom Permission Sets

For edge cases not covered by built-in sets, define inline permission sets:

const assumeAnyRole: PermissionSet = {
  id: "assume-any-role",
  platforms: {
    aws: [{
      grant: { actions: ["sts:AssumeRole"] },
      binding: {
        stack: {
          resources: ["*"],
          condition: { StringEquals: { "sts:ExternalId": "my-ext-id" } }
        }
      }
    }]
  }
}

.permissions({
  profiles: {
    execution: {
      "*": ["storage/data-read", assumeAnyRole],
    }
  }
})

Platform Differences

AspectAWSGCPAzure
IdentityIAM RoleService AccountManaged Identity
Stack scopeARN wildcardsResource-level IAMResource group scope
Resource scopeSpecific ARNsetIamPolicy on resourceRole assignment on resource
Cross-accountAssumeRoleService account impersonationOIDC via Federated Identity

On this page