Skip to main content

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 seven stacks​

StackWhat it holds
alphaagent-org-authA 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-dataNine DynamoDB tables: registered accounts, deployments, provisioning jobs, job steps, audit, admins, locks, usage events and Libraries.
alphaagent-org-jobsTwo DynamoDB tables: job concurrency (leases) and job events.
alphaagent-org-release-cacheOne S3 bucket and one table that catalogue the Studio releases mirrored into this account.
alphaagent-org-foundationThe VPC in the range you chose (two private subnets; with AlphaAgent's NAT gateway also two public subnets and the NAT gateway, with your Transit Gateway neither), 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-private-networkA route per administrator range to your Transit Gateway and the console load balancer's ingress from each; with outbound traffic through your Transit Gateway, the default route to it, sixteen interface endpoints for the AWS services the engine calls in its region, and the route that drops unlisted private ranges. The Transit Gateway attachment itself is created by the installer through the EC2 API. An Organisation installed before private network access has no such stack.
alphaagent-org-appThe internal load balancer in the private subnets and its listener rules (internet-facing on an Organisation installed before private network access), 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:AssumeRole only into roles named AlphaAgentOrgTarget-* (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 prefixed alphaagent-org-.
  • It has no Bedrock, no ecs:RunTask and 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:GetFederationToken and sts:TagSession.

The cross-account trust​

  1. 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.
  2. Launch the template. The console gives you a Launch Stack link into the target account, in its first allowed region, with OrgAccountId, OrgTaskRoleName, ExternalId and RoleNameSuffix pre-filled. The template creates AlphaAgentOrgTarget-<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 that sts:ExternalId matches.
  3. Verify. The console performs one real sts:AssumeRole with the stored External ID and a 900-second session, then, only when the role allows us-east-1, checks for edge stacks left over from a public deployment there. Pass marks the account validated.
  4. Deploy. Every job step mints its own session (RoleSessionName, DurationSeconds, ExternalId), because role chaining caps a session at one hour. A private deployment makes no call outside its region; work in us-east-1 for an existing public deployment uses a sibling session pinned to that region.

The template also accepts AllowedRegions (default: the eleven supported regions; a private deployment needs only its own region, and when the list leaves us-east-1 out the engine makes no us-east-1 call for that account) and EnableApiWafPermissions (default false).

The account template, statement by statement​

Guardrails (Deny). These apply first and cannot be overridden by the Allow statements.

StatementDeniesWhy
DenyAccountAndOrganizationControlorganizations:*, account:*, iam:CreateUser, iam:CreateAccessKey, login profile create/update/delete, sts:GetFederationToken, sts:TagSessionThe role can never create a human identity or change account-level settings
DenyRoleMutationOutsideAlphaAgentCreate, 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
DenyStudioUserImpersonationcognito-idp:AdminCreateUser, AdminSetUserPassword, AdminInitiateAuth, AdminRespondToAuthChallenge, AdminUserGlobalSignOutIt can configure the user pool but never act as one of your users
DenyOutsideAllowedRegionsEverything except IAM, STS, Organizations, Account, CloudFront, Route 53, Support, s3:ListAllMyBuckets and s3:GetBucketLocation, when aws:RequestedRegion is outside AllowedRegionsKeeps regional resources inside the regions you listed

Stacks and compute (Allow).

StatementAllowsUsed for
CloudFormationManageStackscloudformation:*Creating, updating and deleting the five Studio stacks
Ec2AndNetworkec2:*The VPC, subnets, NAT gateway, security groups and endpoints the core stack declares; the Transit Gateway attachment and the private network routes
ElasticLoadBalancingelasticloadbalancing:*The load balancer, listeners, rules and target groups
EcsAndDiscoveryecs:*, servicediscovery:*The cluster, services, task definitions, Service Connect namespace, and the on-demand transfer task
AutoScalingautoscaling:*Capacity provider associations on the cluster
IamForStackRolesiam:* on roles named alphaagent*, AlphaAgent* and aws-service-role/*The task, execution, Lambda and sandbox roles the stacks create
IamAccountLevelReadsiam:ListRolesPreflight name-collision checks

Data and storage (Allow).

StatementAllowsUsed for
DynamoDbTablesdynamodb:* on tables named alphaagent* and their indexesCreating the 38 tables, mirroring API keys, reading the metering outbox and share requests
S3Bucketss3:* on buckets named alphaagent* and alphaagent-org-staging-<account>-*The seven core buckets, the deploy bucket, the frontend upload and Library transfers
AccountLevelReadsdynamodb:ListTables, s3:ListAllMyBuckets, s3:GetBucketLocationDiscovery and preflight
SecretsManagersecretsmanager:* on secrets named alphaagent*Seeding configuration, Neo4j credentials, the origin secret and the licence bootstrap
SecretsManagerAccountLevelReadsListSecrets, GetRandomPasswordDiscovery and minting
MessagingAndEventssqs:*, sns:*, events:*The queues, the alarm topic and the object-created rule
ElastiCacheAndEfselasticache:*, elasticfilesystem:*Redis and the Neo4j file system
KmsForAwsManagedKeyskms:* only when kms:ViaService is S3, Secrets Manager, DynamoDB, SQS, SNS, ElastiCache, EFS, Logs or ECRLets those services use their AWS-managed keys; the role cannot manage KMS keys directly

Application and probe (Allow).

StatementAllowsUsed for
Logs, CloudWatch, Ssmlogs:*, cloudwatch:*, ssm:*Log groups, alarms, metric filters and the two SSM parameters
LambdaSpalambda:*The SPA-serving function, the edge function, and updating sandbox functions after an environment image upgrade
CloudFrontEdgecloudfront:*An existing public deployment's distribution, alias checks and origin-lock verification
EcrPushecr:*Copying Studio images into the account's repositories by digest
CognitoUserPoolscognito-idp:*The user pool, its client, domain and SAML provider
AcmAndServiceQuotasacm:*, servicequotas:*An existing public deployment's us-east-1 certificate, and the preflight quota checks: Elastic IP, VPC and NAT headroom, and the selected models' Bedrock quotas
ValidationProbests:*, bedrock:*Identity checks, and the preflight's model access check (ListInferenceProfiles, GetFoundationModelAvailability); the engine never invokes a model

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 private network template, and an existing public deployment's edge template, are small enough to be sent inline.
  • alphaagent-org-staging-<account>-<region> is created by the account template when CreateStagingBucket is true (the default): SSE-S3 with bucket keys, public access blocked, objects expire after 7 days, incomplete multipart uploads abort after 1 day. It is deleted with the registration stack (DeletionPolicy: Delete), once empty: Clear account empties it, and a bucket that still holds staged copies stops the stack delete with "The bucket you tried to delete is not empty". A registration stack created from an earlier template has DeletionPolicy: Retain, so update it from the current template before deleting it, or empty and delete the bucket it leaves yourself; registering again in that region while such a bucket remains needs CreateStagingBucket set to false. 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, reseed-trust, spa, edge, stateless, private-network, compute, taskdef, settle, saml, doctor.
  • Upgrade: preflight, restore-point, maintenance-on, core, reseed-models, seed-config, reseed-trust, push-image, verify-images, spa, edge, stateless, private-network, compute, taskdef, settle, maintenance-off, doctor, record-release. See Updates and rollback.
  • Reconfigure: preflight, restore-point, maintenance-on, core, reseed-models, reseed-retention, reseed-network, reseed-trust, edge, stateless, private-network, delete-edge, taskdef, settle, maintenance-off, doctor, record-config.
  • Rollback: rollback, private-network, reseed-network, reseed-trust, settle, maintenance-off.
  • Uninstall: grace, predrain, delete taskdef and compute, delete private network (the routes stack, then the Transit Gateway attachment), delete stateless and edge, delete environment functions, delete core.

On a private deployment the edge steps are skipped by name; on an existing public one the private network steps are. The private-network step parks on your network team's acceptance of the attachment when your Transit Gateway does not accept attachments automatically.

Before updating an existing public deployment's 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. A private deployment never reads it for this.

Steps: verify the trust in a Studio account​

  1. Open the role AlphaAgentOrgTarget-prod and read its trust policy. One principal, your Organisations account's alphaagent-org-task-role, with StringEquals on sts:ExternalId.
  2. Open Permissions and confirm the four managed policies (Guardrails, StacksAndCompute, DataAndStorage, AppAndProbe), plus ApiWaf only if you enabled it.
  3. In the Organisations console, open the account and use Verify. The assume-role check should pass.
  4. In CloudTrail in the Studio account (if you have enabled it), filter AssumeRole events 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 MaxSessionDuration is 3600 seconds and no policy allows iam:CreateUser.
  • The staging bucket, if created, is empty except during a Library transfer and for seven days after it.

Limits​

  • One AlphaAgentOrgTarget-<suffix> role per suffix per account. A second role in the same account and region must set CreateStagingBucket to false, because the bucket name is per account and region.
  • A service control policy that denies sts:AssumeRole from 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, or RoleNameSuffix was 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.
  • An update of an existing public deployment fails because the registration stack is stale: update the account template to 2.3.0 or later and make sure us-east-1 is in AllowedRegions.