CloudFormation Deployment
Overview
The Britive onboarding repository ships one CloudFormation template, britive_integration_resources.yaml, and four ways to deploy it:
| Option | Directory | Scope |
|---|---|---|
| Single account | single-account-stack/ | A standalone account, a POC, or the management account of an organization |
| Member accounts | stackset-templates/ | Every account under one or more OUs, with auto-deployment for accounts that join later |
| Whole organization | organization-stackset/ | Management account and member accounts from one stack (nested stack + StackSet) |
| Full lab | full-lab-setup/ | A disposable demo: integration, sample roles, Linux/Windows/MySQL targets in their own VPC |
All of it is in cloudformation/aws/, with a generate-parameters.sh helper and a sample Service Control Policy.
What the Template Creates
| Resource | Name | Notes |
|---|---|---|
| SAML Identity Provider | britive-<tenant> | From the metadata XML you download from the tenant |
| Integration role | britive-<tenant>-integration-role | IAMReadOnlyAccess + AWSOrganizationsReadOnlyAccess; trusts the provider for sts:AssumeRoleWithSAML, sts:SetSourceIdentity, sts:TagSession with SAML:aud pinned |
Session invalidation (DeployAwsInvalidationFeature, default true) | inline policy | iam:*Policy* on policy/britive/managed/* |
Access Builder (DeployAccessBuilder) | inline policy | iam:*Role* on role/britive/managed/* |
AI identity scanning (DeployAiIdentityScanning) | managed policy | AmazonBedrockReadOnly |
Sample JIT roles (DeploySampleRoles) | Readonly-admin-role, Poweruser-role, EC2-Fullaccess-role, S3-Fullaccess-role | Demonstrations; same trust policy as any role Britive brokers |
MaxSessionDuration (default 3600 seconds) is what you enter, in hours, as Duration of backend connection in the Britive application.
Before You Begin
- A Britive tenant with administrator access
- AWS credentials that can create IAM roles, policies and SAML providers in the target account; the StackSet options also need the management account (or a StackSets delegated administrator) with trusted access enabled
- AWS CLI v2 installed and configured
Step 1 — Download the SAML Metadata and Generate the Parameters
Download the metadata file
In the Britive console, go to System Administration → Security → SAML Configurations → Download SAML Metadata. It contains only Britive’s public signing certificate, but it identifies your tenant, so keep it out of version control.
Generate the parameters file
The CLI needs the XML JSON-escaped on one line, which is tedious by hand. The helper writes a complete parameters file:
git clone https://github.com/britive/onboarding.git
cd onboarding/cloudformation/aws
./generate-parameters.sh your-tenant /path/to/britive-saml-metadata.xml
# writes ./parameters.json (gitignored)Flags: --sample-roles, --access-builder, --ai-scanning, --no-invalidation, --max-session <seconds>, -o <file>.
In the AWS console you can paste the multi-line XML straight into the SAML metadata XML parameter instead.
Option 1 — Single Account
Directory: cloudformation/aws/single-account-stack/
The quickest path to connecting one account. Also what the management account of an organization needs, because service-managed StackSets never deploy there.
aws cloudformation deploy \
--stack-name britive-integration \
--template-file britive_integration_resources.yaml \
--parameter-overrides file://parameters.json \
--capabilities CAPABILITY_NAMED_IAM
aws cloudformation describe-stacks --stack-name britive-integration \
--query 'Stacks[0].Outputs' --output tableParameters:
| Parameter | Default | Description |
|---|---|---|
TenantName | — | Tenant subdomain (mycompany for mycompany.britive-app.com) |
SamlMetadataDocumentXmlContent | — | The metadata XML |
DeployAwsInvalidationFeature | true | Session-invalidation permissions |
DeployAccessBuilder, DeployAiIdentityScanning, DeploySampleRoles | false | Optional permissions and demo roles |
MaxSessionDuration | 3600 | Integration role session length, seconds |
Outputs: AccountId, BritiveSamlProviderName, BritiveIntegrationRoleName, MaxSessionDurationSeconds — the values for Step 2.
Option 2 — Member Accounts with a StackSet
Directory: cloudformation/aws/stackset-templates/
Deploys the same template to every account under the OUs you target with a service-managed StackSet. Accounts that join those OUs later are onboarded automatically. The management account is not included — deploy Option 1 there as well, or use Option 3.
Prerequisites: credentials for the management account (or a delegated administrator, adding --call-as DELEGATED_ADMIN), AWS Organizations with all features enabled, and trusted access for StackSets:
aws organizations enable-aws-service-access \
--service-principal member.org.stacksets.cloudformation.amazonaws.comaws cloudformation create-stack-set \
--stack-set-name britive-integration \
--template-body file://britive_integration_resources.yaml \
--parameters file://parameters.json \
--permission-model SERVICE_MANAGED \
--auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false \
--capabilities CAPABILITY_NAMED_IAM
aws cloudformation create-stack-instances \
--stack-set-name britive-integration \
--deployment-targets OrganizationalUnitIds=r-xxxx \
--regions us-east-1 \
--operation-preferences FailureToleranceCount=10,MaxConcurrentCount=10,RegionConcurrencyType=PARALLELIAM is global, so one region is enough. Replace r-xxxx (the root, from aws organizations list-roots) with specific OU IDs to limit scope. Watch the rollout with aws cloudformation list-stack-instances --stack-set-name britive-integration.
Option 3 — Whole Organization in One Stack
Directory: cloudformation/aws/organization-stackset/
A wrapper template, deploy_britive_integration_resources.yaml, deploys the integration template twice from the management account: as a nested stack in the management account itself, and as a service-managed StackSet to the member accounts. Both read the template from an S3 bucket in the management account, in the same region as the stack.
aws s3 cp britive_integration_resources.yaml s3://my-britive-templates/
cd organization-stackset
cp parameters.example.json parameters.json
# set S3BucketName, OrganizationalUnitIds, TenantName; paste the escaped
# SamlMetadataDocumentXmlContent value generated in Step 1
aws cloudformation deploy \
--stack-name britive-organization \
--template-file deploy_britive_integration_resources.yaml \
--parameter-overrides file://parameters.json \
--capabilities CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPANDOutputs: ManagementAccountId, IdentityProviderName, IntegrationRoleName, BackendConnectionDurationHours.
The Terraform version of this option (terraform/aws/organization-stackset/) reads the template from the repository and needs no bucket.
Option 4 — Full Lab
Directory: cloudformation/aws/full-lab-setup/
A complete environment to demonstrate Britive on AWS. For demonstrations and proofs of concept only.
Resources created:
- The integration (SAML provider, integration role, invalidation permissions) and the four sample JIT roles
- VPC
10.0.0.0/16, two public subnets, internet gateway; a security group open toAllowedIngressCidronly (0.0.0.0/0is rejected by a template rule) - Amazon Linux 2023
t3.microand Windows Server 2022t3.smallinstances, IMDSv2, encrypted disks, one key pair whose private key EC2 stores in Parameter Store - RDS MySQL
db.t3.micro, encrypted with a KMS key, credentials in Secrets Manager, deleted with the stack
The lab costs roughly USD 50/month (two instances and an RDS instance; there is no NAT gateway). Delete the stack when the demo is over.
./generate-parameters.sh your-tenant /path/to/britive-saml-metadata.xml -o /tmp/base.json
cd full-lab-setup
cp parameters.example.json parameters.json
# copy SamlMetadataDocumentXmlContent from /tmp/base.json; set TenantName and
# AllowedIngressCidr to your public IP as a /32 (curl -s https://checkip.amazonaws.com)
aws cloudformation deploy \
--stack-name britive-lab \
--template-file britive_lab_resources.yaml \
--parameter-overrides file://parameters.json \
--capabilities CAPABILITY_NAMED_IAM
# 10-15 minutes, mostly RDSThe outputs include LinuxInstancePublicIp, WindowsInstanceId, WindowsInstancePublicIp, RdsEndpoint, RdsSecretArn and KeyPairId; the directory README shows how to fetch the key from Parameter Store and reach each target.
Step 2 — Register the AWS Account in Britive
Get the stack outputs
aws cloudformation describe-stacks --stack-name britive-integration \
--query 'Stacks[0].Outputs' --output tableAdd the application
In the Britive console, go to System Administration → Tenant Applications → Create Application and choose AWS Standalone for a single account or AWS for an organization (the management account must have the resources). Enter:
| Field | Single account / lab output | Whole-organization output |
|---|---|---|
| Account ID / Management Account ID | AccountId | ManagementAccountId |
| Identity Provider Name | BritiveSamlProviderName | IdentityProviderName |
| Integration Role Name (the name, not the ARN) | BritiveIntegrationRoleName | IntegrationRoleName |
| Duration of backend connection (hours) | MaxSessionDurationSeconds ÷ 3600 (lab: BackendConnectionDurationHours) | BackendConnectionDurationHours |
Save and test
Click Save and Test. Britive scans the account — or, for an organization, every member account the StackSet reached. This takes 1–3 minutes.
Verify
Go to Applications → AWS → Environments and confirm the account appears with a green status indicator. Sample roles, if deployed, appear as permissions you can attach to a profile.
Protecting the Britive-Managed Paths
With session invalidation or Access Builder enabled, apply the Service Control Policy in cloudformation/aws/scp/ from the management account, so nothing but the integration role can modify policy/britive/managed/* and role/britive/managed/*.
Verify End-to-End
# After checking out an IAM role profile in Britive, set the credentials
export AWS_ACCESS_KEY_ID=<from checkout>
export AWS_SECRET_ACCESS_KEY=<from checkout>
export AWS_SESSION_TOKEN=<from checkout>
aws sts get-caller-identity
# Expected: the assumed-role ARN, e.g. arn:aws:sts::123456789012:assumed-role/Poweruser-role/britive-sessionAfter checking in (or session expiry):
aws sts get-caller-identity
# Expected: ExpiredTokenException — session token is no longer validUpdating and Removing
A new SAML certificate means a new metadata file: run generate-parameters.sh again and re-run the same deploy (or update-stack-set) command. aws cloudformation deploy keeps parameters you do not pass; with update-stack, pass UsePreviousValue=true for every unchanged parameter.
Remove the application from Britive before deleting a stack. Deleting also needs iam:DeleteRole, iam:DeleteRolePolicy, iam:DetachRolePolicy and iam:DeleteSAMLProvider.
Troubleshoot
| Symptom | Cause | Fix |
|---|---|---|
Invalid SAML metadata during stack deploy | Not the full XML, or escaped by hand | Use generate-parameters.sh; check the source with xmllint --noout file.xml |
Role … already exists | A previous deployment left the role behind | Delete it (detach managed and delete inline policies first) or use a different tenant name |
| Save and Test fails for an AWS (organization) application | Integration role missing in the management account | Service-managed StackSets skip it; deploy Option 1 there, or use Option 3 |
StackSet reports trusted access errors | Trusted access for StackSets not enabled | aws organizations enable-aws-service-access --service-principal member.org.stacksets.cloudformation.amazonaws.com |
StackSet instance FAILED: already exists | The member account already has the role | Delete it there; FailureToleranceCount lets the other accounts continue |
TemplateURL must be an Amazon S3 URL (Option 3) | Bucket in another region, or the object is missing | Bucket and stack must share a region |
Lab stack rejected: AllowedIngressCidr must not be 0.0.0.0/0 | The template rule | Use your public IP as a /32 |
| Session not invalidated at checkin | DeployAwsInvalidationFeature=false | Redeploy with it true; it grants iam:*Policy* on policy/britive/managed/* |