What runs in your account (Organisations)
AlphaAgent Organisations is the control plane you run yourself. It deploys, updates and removes Studio in your other accounts, and it does so through a role you create in each of those accounts. This page covers what the Organisations account contains, how the cross-account trust works, what each permission in the account template is for, and how deployment jobs run.
Who this is for
Security engineers approving the account template, and cloud engineers who will run orgctl.py and register accounts.
Before you start
You will get more from this page with the account template open. The Organisations console offers it for download when you add an account; its TemplateVersion output is 2.3.0.
The six stacks
| Stack | What it holds |
|---|---|
alphaagent-org-auth | A Cognito user pool, its app client and hosted domain, one secret and one SSM parameter. After the saml install step the pool federates to your identity provider and password sign-in is off. |
alphaagent-org-data | Nine DynamoDB tables: registered accounts, deployments, provisioning jobs, job steps, audit, admins, locks, usage events and Libraries. |
alphaagent-org-jobs | Two DynamoDB tables: job concurrency (leases) and job events. |
alphaagent-org-release-cache | One S3 bucket and one table that catalogue the Studio releases mirrored into this account. |
alphaagent-org-foundation | The VPC (four subnets, one NAT gateway), three security groups, nine VPC endpoints, three buckets (bundle-cache, frontend, cfn-templates), five ECR repositories, six secret shells and three log groups. No IAM resources. |
alphaagent-org-app | The load balancer and listener rules, the ECS cluster, two task definitions and services (org-api and org-provisioner), the SPA-serving Lambda function, three IAM roles, an SNS topic for worker alerts, four alarms and a log group. |
The install runs twelve steps in order: preflight, org-auth, foundation, push-image, seed-config, spa, app, settle, console-credential, saml, bootstrap-admin, doctor. Every write outside CloudFormation is listed on Everything AlphaAgent deploys.
The engine
The org-provisioner service polls for work: provisioning jobs, share and pull requests from Studio deployments (every 60 seconds), usage mirroring from each deployment's metering outbox (every 120 seconds), API-key materialisation, health, and Update Manager rules. org-api serves the Organisations console. Both run as the alphaagent-org-task-role role.
That role's policy is what makes the cross-account model work, and it is deliberately narrow:
- It may
sts:AssumeRoleonly into roles namedAlphaAgentOrgTarget-*(under the/alphaagent-org/path or without a path). Which account is decided by the registered-account row, not by the policy. - It reads and writes only the Organisations tables (
alphaagent-org-*), the three foundation buckets, and secrets prefixedalphaagent-org-. - It has no Bedrock, no
ecs:RunTaskand no data-plane permission in any Studio account. Every call into a Studio account goes through the assumed target role. - It explicitly denies
iam:CreateUser,iam:CreateAccessKey, login-profile changes,organizations:*,account:*,sts:GetFederationTokenandsts:TagSession.
The cross-account trust
- Register. In the Organisations console you add an AWS account. The console generates a 32-character External ID, stores it on the account row, shows it once, and shows its fingerprint (the first 12 hex characters of its SHA-256) so you can compare it later.
- Launch the template. The console gives you a Launch Stack link into the target account with
OrgAccountId,OrgTaskRoleName,ExternalIdandRoleNameSuffixpre-filled. The template createsAlphaAgentOrgTarget-<suffix>with path/alphaagent-org/and a one-hour maximum session, trusting exactly one principal,arn:aws:iam::<your Organisations account>:role/alphaagent-org-task-role, on the condition thatsts:ExternalIdmatches. - Verify. The console performs one real
sts:AssumeRolewith the stored External ID and a 900-second session, then checks for edge stacks left over from a previous deployment inus-east-1. Pass marks the account validated. - Deploy. Every job step mints its own session (
RoleSessionName,DurationSeconds,ExternalId), because role chaining caps a session at one hour. Work inus-east-1uses a sibling session pinned to that region.
The template also accepts AllowedRegions (default: the eleven supported regions) and EnableApiWafPermissions (default false).
The account template, statement by statement
Guardrails (Deny). These apply first and cannot be overridden by the Allow statements.
| Statement | Denies | Why |
|---|---|---|
DenyAccountAndOrganizationControl | organizations:*, account:*, iam:CreateUser, iam:CreateAccessKey, login profile create/update/delete, sts:GetFederationToken, sts:TagSession | The role can never create a human identity or change account-level settings |
DenyRoleMutationOutsideAlphaAgent | Create, delete, update, attach, detach, put, delete-policy and pass on any role not named alphaagent*, AlphaAgent* or under aws-service-role/ | It manages only the roles the Studio stacks declare |
DenyStudioUserImpersonation | cognito-idp:AdminCreateUser, AdminSetUserPassword, AdminInitiateAuth, AdminRespondToAuthChallenge, AdminUserGlobalSignOut | It can configure the user pool but never act as one of your users |
DenyOutsideAllowedRegions | Everything except IAM, STS, Organizations, Account, CloudFront, Route 53, Support, s3:ListAllMyBuckets and s3:GetBucketLocation, when aws:RequestedRegion is outside AllowedRegions | Keeps regional resources inside the regions you listed |
Stacks and compute (Allow).
| Statement | Allows | Used for |
|---|---|---|
CloudFormationManageStacks | cloudformation:* | Creating, updating and deleting the five Studio stacks |
Ec2AndNetwork | ec2:* | The VPC, subnets, NAT gateway, security groups and endpoints the core stack declares |
ElasticLoadBalancing | elasticloadbalancing:* | The load balancer, listeners, rules and target groups |
EcsAndDiscovery | ecs:*, servicediscovery:* | The cluster, services, task definitions, Service Connect namespace, and the on-demand transfer task |
AutoScaling | autoscaling:* | Capacity provider associations on the cluster |
IamForStackRoles | iam:* on roles named alphaagent*, AlphaAgent* and aws-service-role/* | The task, execution, Lambda and sandbox roles the stacks create |
IamAccountLevelReads | iam:ListRoles | Preflight name-collision checks |
Data and storage (Allow).
| Statement | Allows | Used for |
|---|---|---|
DynamoDbTables | dynamodb:* on tables named alphaagent* and their indexes | Creating the 38 tables, mirroring API keys, reading the metering outbox and share requests |
S3Buckets | s3:* on buckets named alphaagent* and alphaagent-org-staging-<account>-* | The seven core buckets, the deploy bucket, the frontend upload and Library transfers |
AccountLevelReads | dynamodb:ListTables, s3:ListAllMyBuckets, s3:GetBucketLocation | Discovery and preflight |
SecretsManager | secretsmanager:* on secrets named alphaagent* | Seeding configuration, Neo4j credentials, the origin secret and the licence bootstrap |
SecretsManagerAccountLevelReads | ListSecrets, GetRandomPassword | Discovery and minting |
MessagingAndEvents | sqs:*, sns:*, events:* | The queues, the alarm topic and the object-created rule |
ElastiCacheAndEfs | elasticache:*, elasticfilesystem:* | Redis and the Neo4j file system |
KmsForAwsManagedKeys | kms:* only when kms:ViaService is S3, Secrets Manager, DynamoDB, SQS, SNS, ElastiCache, EFS, Logs or ECR | Lets those services use their AWS-managed keys; the role cannot manage KMS keys directly |
Application and probe (Allow).
| Statement | Allows | Used for |
|---|---|---|
Logs, CloudWatch, Ssm | logs:*, cloudwatch:*, ssm:* | Log groups, alarms, metric filters and the two SSM parameters |
LambdaSpa | lambda:* | The SPA-serving function, the edge function, and updating sandbox functions after an environment image upgrade |
CloudFrontEdge | cloudfront:* | The distribution, alias checks and origin-lock verification |
EcrPush | ecr:* | Copying Studio images into the account's repositories by digest |
CognitoUserPools | cognito-idp:* | The user pool, its client, domain and SAML provider |
AcmAndServiceQuotas | acm:*, servicequotas:* | The us-east-1 certificate and the preflight quota check |
ValidationProbe | sts:*, bedrock:* | Identity checks; the engine performs no Bedrock probe today |
WAF (Allow, only with EnableApiWafPermissions=true). wafv2:* on regional Web ACLs and IP sets named alphaagent* and on load balancers named alphaagent*, plus CheckCapacity, ListWebACLs and ListIPSets.
Staging and deploy buckets
alphaagent-deploy-<account>-<region>is created by the engine on first use in the deployment region: public access blocked, SSE-S3, versioning. Stack templates are uploaded here and passed to CloudFormation by URL. The edge template is small enough to be sent inline, so nothing is created inus-east-1outside the stack.alphaagent-org-staging-<account>-<region>is created by the account template whenCreateStagingBucketistrue(the default): SSE-S3 with bucket keys, public access blocked, objects expire after 7 days, incomplete multipart uploads abort after 1 day,DeletionPolicy: Retain. Library transfers of knowledge graph versions stage the exported graph here: a one-shot task in the source deployment exports to its staging bucket, the engine copies between the two accounts' staging buckets, and a second task in the target imports.
The job model
Every install, upgrade, reconfigure, rollback and uninstall is a job row with ordered step records and an event stream, visible in the Organisations console. The provisioner claims a job through a lease, runs one step at a time, and records each step's outcome. A step can park rather than fail: a preflight FAIL parks on an override decision, and a SAML configuration that needs your metadata parks until you supply it.
Step orders:
- Install: preflight, core, neo4j-creds, push-image, verify-images, seed-config, spa, edge, stateless, compute, taskdef, settle, saml, doctor.
- Upgrade: preflight, restore-point, maintenance-on, core, reseed-models, seed-config, push-image, verify-images, spa, edge, stateless, compute, taskdef, settle, maintenance-off, doctor, record-release. See Updates and rollback.
- Uninstall: grace, predrain, delete taskdef, compute, stateless and edge, delete environment functions, delete core.
Before deploying the front door, the engine reads the registration stack in the target account and refuses with a permission error if its TemplateVersion is below 2.3.0 or us-east-1 is missing from AllowedRegions.
Steps: verify the trust in a Studio account
- Open the role
AlphaAgentOrgTarget-prodand read its trust policy. One principal, your Organisations account'salphaagent-org-task-role, withStringEqualsonsts:ExternalId. - Open Permissions and confirm the four managed policies (
Guardrails,StacksAndCompute,DataAndStorage,AppAndProbe), plusApiWafonly if you enabled it. - In the Organisations console, open the account and use Verify. The
assume-rolecheck should pass. - In CloudTrail in the Studio account (if you have enabled it), filter
AssumeRoleevents for that role: every session name begins with the job or step that opened it.
What you should see
- The External ID fingerprint shown in the Organisations console matches the SHA-256 of the value you pasted into the stack.
- The role's
MaxSessionDurationis 3600 seconds and no policy allowsiam:CreateUser. - The staging bucket, if created, is empty except during a Library transfer.
Limits
- One
AlphaAgentOrgTarget-<suffix>role per suffix per account. A second role in the same account and region must setCreateStagingBuckettofalse, because the bucket name is per account and region. - A service control policy that denies
sts:AssumeRolefrom your Organisations account into the Studio account blocks every job at its first step; see SCPs and guardrails. - The engine does not use StackSets. Each account is registered and verified individually.
If something goes wrong
- Verify fails on
assume-role: the stack was run in a different account, the External ID was not copied exactly, orRoleNameSuffixwas changed. The check's remediation text says which to check. - A job fails with a permission error naming an action: the target account has a service control policy or permission boundary that removes an action the template grants. The failure text names the action.
- A deploy fails because the registration stack is stale: update the account template to
2.3.0or later and make sureus-east-1is inAllowedRegions.