Docs

Permissions

How Alien manages access control across AWS, GCP, and Azure using permission profiles.

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 manage deployments. Controlled by frozen and live. Management permissions never include data access — Alien can update your function's code but can't read from storage or vaults.
  3. Application runtime — What your deployed code can access. Controlled by permission profiles. This page covers this layer.

Resources are isolated by default. A function 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 function 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 function:

const api = new alien.Function("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
Functionexecute, invoke

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 functions 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 function 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 the minimum management access from the frozen/live choice — frozen resources get read-only health checks, live resources get update permissions. Neither includes data access.

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