Skip to content

About

Setup files for deploying Insight Factory into your own AWS accounts.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Insight Factory on AWS: installation files

Setup files for deploying Insight Factory into your own AWS accounts.

Your team deploys one CloudFormation stack per AWS account. It creates an identity provider entry and one IAM role, and it is the only thing Insight Factory needs from you. No password, access key, or AWS credential of any kind is shared with us.

If you keep Insight Factory's Terraform state in your own S3 bucket, you also deploy a second, much smaller stack once, in the bucket's account. See If you keep the Terraform state yourself.

Everything in this repository is public so that your cloud and security teams can read it, check it against the checksums below, and keep a copy of exactly what they reviewed, without needing an account or asking us for access.


What you deploy

insightfactory-aws-access.yaml is about 900 lines, with no external dependencies. It creates four things:

Resource What it is
GitHubOidcProvider An identity provider entry telling your account to trust tokens issued by GitHub Actions. Created once per account.
IFTerraform (IAM role) The role our automation assumes to build and maintain the platform. No user, no key, no password.
IFTerraformDeployIam, ...Network, ...Data, ...Compute (managed policies) The individual actions the role may call, split by job. Four policies because one would exceed AWS's size limit for a managed policy.
IFTerraformBoundary (managed policy) The ceiling on every IAM role the deployment later creates. Yours to read, and yours to tighten.

In the normal case there is nothing to fill in. Everything the stack trusts (the repository and branch, our CI addresses, the session length, the policy names) is written into the template rather than asked of you, so none of it can drift between the file your security team reviewed and the stack you deployed. Changing any of it means a new version of the template, not an edit to your copy.

Four parameters remain, all with working defaults, because your account and your organisation decide them rather than us: whether to create the identity provider entry, the IAM path, whether to place one of your own permissions boundaries on the role, and whether our access is currently enabled. See Parameters.

How access works

Rather than holding credentials for your account, our automation presents a short-lived, cryptographically signed token that GitHub issues each time it runs, and your account exchanges that token for a temporary session in the role above.

The role's trust policy accepts a token only if both claims match exactly:

  • aud is sts.amazonaws.com, so a token minted for any other service cannot be replayed here.

  • sub is one repository on one branch, matched exactly rather than by pattern. No other repository on GitHub, including our own, can obtain a session.

    The value names the organisation and the repository by id (76498963 and 1307263479) rather than by name, which is the form GitHub issues for ours. An id cannot be given up and claimed by someone else the way a name can, so a repository renamed to ours afterwards still would not match. The name-based spelling is not accepted.

And only from four addresses. Our release pipelines have static egress, two in the primary region and two in the failover region, and the trust policy names them, so the role cannot be assumed from anywhere else even if something were mis-scoped on our side. The addresses identify an Insight Factory CI job; the repository and branch identify the pipeline. They are independent layers and neither replaces the other. If our addresses ever change, that is a new version of this template and a stack update for you. That is the point: our CI cannot move without you seeing it.

The condition applies to the role-assumption call only, not to the role's permissions, so it never interferes with AWS services acting on the role's behalf afterwards. See scoping note 5 in the template for why.

There is no shared secret in this arrangement, so there is nothing to rotate, nothing to leak, and nothing to revoke except the role itself.

What the role can and cannot do

Two independent limits, and the second holds regardless of the first.

What it can reach. The role is attached to four managed policies this stack creates, which between them name 373 individual actions. Every action is written in full: there is no asterisk anywhere in the four documents, so "can it do X" is a search of a list rather than a judgement about what a wildcard covers.

Those actions fall inside the twenty-one services the platform uses: ecr, ec2, ecs, elasticloadbalancing, acm, s3, kms, secretsmanager, lambda, glue, rds, elasticache, sns, sqs, scheduler, logs, cloudwatch, xray, bedrock, iam, sts, plus the tagging API. Every other AWS service is absent, and so is every action within those twenty-one that the deployment does not call. Read IFTerraformDeployIam, IFTerraformDeployNetwork, IFTerraformDeployData and IFTerraformDeployCompute in the template for the exact documents.

iam is in that list because the deployment creates and maintains the roughly fifteen IAM roles the platform's own services run under. Four grants bound what that means:

  1. It can only touch its own identities. Every role and policy the deployment creates lives under IamPath (default /insightfactory/), and the IAM grants are scoped to that path by resource ARN. iam:PassRole is scoped to it too, so the role cannot hand one of your existing privileged roles to a function it creates.
  2. Every role it creates carries the boundary. iam:CreateRole is allowed only with IFTerraformBoundary as the new role's permissions boundary, as a condition on the grant itself, so no role it makes can exceed that ceiling.
  3. It can attach only its own policies, or five named AWS ones. iam:AttachRolePolicy is conditioned on the policy ARN: policies under IamPath, plus AWSLambdaBasicExecutionRole, AWSLambdaVPCAccessExecutionRole, AWSGlueServiceRole, AmazonECSTaskExecutionRolePolicy and AWSXRayDaemonWriteAccess.
  4. It cannot edit its own ceiling. The policies that bound the role, including IFTerraformBoundary, are created at your account root, outside every scope the role is granted.

iam:CreateUser and iam:CreateAccessKey are not in any of the four policies, which makes "no users, no keys" a property your account enforces rather than a claim we make. Nor is any IAM group action or user policy attachment: the deployment creates no group, and your people's access is managed policies under IamPath that you attach to your own groups or IAM Identity Center permission sets.

What it cannot do, whatever policy is attached. IFTerraformBoundary is the ceiling on every IAM role the deployment creates, and it is the complete answer to "what is the most any Insight Factory role in my account can ever do". A boundary is an allow-list, so everything absent from it is capped out; what prevents privilege escalation is the absence of iam from that policy. It also denies outright the account-level controls a reviewer looks for: AWS Organizations, account settings, CloudTrail logging, GuardDuty, Security Hub and Config.

If a deployment stops on an AccessDenied. The action list is derived from the resource types the deployment declares and checked against CloudTrail from live installations, so on a first install it may still prove very slightly incomplete. The failure mode is loud: an apply that stops part-way, not a silent gap. There is no parameter to widen it with: tell us what failed and we will issue a corrected version of this template. That keeps the change reviewable and recorded, rather than made once in your account and forgotten.

Before you start

  • The AWS accounts that will host the platform. A full installation is one account per environment plus one shared account.
  • Permission in them to create an IAM role, an IAM identity provider, an IAM managed policy and a CloudFormation stack. That normally means an administrator.
  • The region decided.

Verify the download

The checksums are published here, in this repository, rather than in the email that pointed you at it. Check the file you downloaded against them before you deploy it.

# macOS
shasum -a 256 -c SHA256SUMS

# Linux
sha256sum -c SHA256SUMS

If it does not match, stop and contact us. Do not deploy it.

Deploy

Deploy the stack once in each account, and create it in the region the platform will run in, so the stack records the right one for us. Either route below works; they do the same thing.

Console

  1. Open CloudFormation, check the region in the top-right corner, and choose Create stack → With new resources.
  2. Choose Upload a template file and select insightfactory-aws-access.yaml.
  3. Name the stack insightfactory-access and continue past the parameters as they are, unless your organisation's standards require a different IamPath or a permissions boundary on the role.
  4. On the last page, acknowledge that the stack creates IAM resources with custom names, and create it.
  5. When it reaches CREATE_COMPLETE, open the Outputs tab.

CLI

aws cloudformation deploy \
  --template-file insightfactory-aws-access.yaml \
  --stack-name insightfactory-access \
  --region <your-region> \
  --capabilities CAPABILITY_NAMED_IAM

aws cloudformation describe-stacks \
  --stack-name insightfactory-access \
  --region <your-region> \
  --query 'Stacks[0].Outputs'

What to send us

Three values per account, from the Outputs tab. None of them is a secret.

Output
AwsAccountId The account you deployed into
Region The region the stack was created in
RoleArn The role our automation will assume

Send them to deployments@insightfactory.ai, and tell us which account is which: which are the environment accounts and which is the shared one.

Also send IamPath if you changed it from the default. Our deployment must be configured with the same value, and its first apply is denied if it is not. And tell us if you set PermissionsBoundaryArn. The remaining outputs (OidcProviderArn, DeployPolicyArns and BoundaryPolicyArn) are for you to read. There is nothing to send for any of them.

Parameters

Four, and each exists because your account or your organisation decides it rather than us. All four have working defaults, and the defaults are correct unless your organisation imposes a standard of its own.

Parameter Default
CreateOidcProvider Yes Set to No only if this account already trusts GitHub Actions from an earlier stack. An account holds one entry per identity provider, and a second attempt fails as a duplicate.
IamPath /insightfactory/ The path every role and policy the deployment creates is confined to. Change it if your IAM naming standard requires, and tell us, because our deployment must be configured with the same value or its first apply is denied. A bare / is refused: it would put our roles at your account root, where the policies could no longer tell ours apart from yours.
InsightFactoryAccess Enabled The switch for our access. Disabled turns the role's trust policy into a deny: no new session can be obtained, nothing is deleted, and your Insight Factory keeps running, because nothing it runs uses IFTerraform. Set it back to Enabled for the next release. See Revoking access.
PermissionsBoundaryArn (empty) Optional. If your organisation requires a permissions boundary on every IAM principal, supply its ARN and it is applied to IFTerraform. Tell us if you set it. Your boundary intersects with everything the role is granted, so one narrower than the platform needs fails a deployment part-way through, with resources already created.

PermissionsBoundaryArn is a boundary your organisation places on IFTerraform. IFTerraformBoundary is the ceiling we place on the roles IFTerraform later creates. Both can be set, and they do not interact.

Everything else is fixed in the template: the trusted repository and branch, our CI addresses, the four-hour maximum session, and the policy names. Read them in the file, which is now the only place they can be.

If you tighten IFTerraformBoundary, tell us. Loosening it is harmless. Tightening it below what the platform needs fails a deployment part-way through, with resources already created.

If you keep the Terraform state yourself

The Terraform state is the record of every resource the deployment has created in your accounts. By default Insight Factory keeps it. If you would rather keep it in an S3 bucket of your own, insightfactory-terraform-state.yaml creates the one role our automation needs to reach it, IFTerraformState.

The role can reach that bucket and nothing else. It may list the bucket, read and write its objects, and delete only the lock files Terraform removes when it releases a lock (*.tflock). It cannot delete a state file, but writing one can overwrite it, so keep versioning on: that is what lets an earlier state be recovered. With KmsKeyArn it may also use that one key for the bucket's objects. It has no other S3 access, no other service and no IAM action.

It trusts exactly what IFTerraform trusts: the same repository and branch by id, the same four CI addresses, the same four-hour session and the same InsightFactoryAccess switch.

  1. Create the bucket first. One bucket for every environment, used for nothing else, with versioning on so an earlier state can be recovered, and public access blocked. Terraform writes the state with SSE-S3, so a bucket policy must not refuse SSE-S3 uploads. Nor should it refuse uploads that carry no encryption header: our release automation writes two small marker files beside the state without one, and a refusal fails the release after its changes are applied. The bucket's default encryption covers those files anyway.

  2. Deploy the stack once, in the bucket's account. Leave CreateOidcProvider as No where insightfactory-access is already deployed in that account, which is the usual case; set it to Yes only where nothing in the account trusts GitHub yet.

    aws cloudformation deploy \
      --template-file insightfactory-terraform-state.yaml \
      --stack-name insightfactory-terraform-state \
      --region <your-region> \
      --parameter-overrides StateBucketName=<your-bucket> \
      --capabilities CAPABILITY_NAMED_IAM
  3. Send us the bucket name, the bucket's Region and the RoleArn output, with the rest of your installation workbook.

Parameter Default
StateBucketName (required) The bucket. It must already exist.
KmsKeyArn (empty) Only if the bucket's default encryption is a customer-managed KMS key: its ARN. Its key policy must allow IAM policies in the account to grant its use.
CreateOidcProvider No Yes only where the account has no GitHub identity provider entry yet.
PermissionsBoundaryArn (empty) As in the access stack. It must allow the S3 actions above on the bucket, and with KmsKeyArn also kms:Decrypt and kms:GenerateDataKey on that key.
InsightFactoryAccess Enabled As in the access stack. Disabled refuses every new session; the state stays in your bucket.

Revoking access

To suspend access, update the stack and set InsightFactoryAccess to Disabled. The role's trust policy becomes a deny, so our automation cannot obtain a new session. Nothing is deleted, and your Insight Factory keeps running: its functions, containers and databases use their own roles, never IFTerraform. Releases, schema deployments and fixes wait until you set it back to Enabled, which is the same stack update.

A session issued before the change stays valid until it expires, at most four hours. To end it at once, open the IFTerraform role in the IAM console and choose Revoke active sessions, which denies every session issued before that moment (AWS documentation).

To remove access entirely, delete the stack. Every session our automation could obtain disappears with the role, and there is no credential that outlives it.

If you keep the Terraform state yourself, insightfactory-terraform-state has the same InsightFactoryAccess switch, and IFTerraformState the same Revoke active sessions. To suspend our access fully, set Disabled in both stacks, and revoke sessions on both roles. Deleting the state stack removes IFTerraformState and leaves the bucket and the state in it untouched.

Both changes are yours to make, and we cannot undo either from our side.

Auditing

Every action our automation takes appears in your CloudTrail under an assumed-role session. Each deployment is also preceded by a Terraform plan, a dry run listing every resource it would create and changing nothing, which we share with you and which needs your approval before anything is applied.

Questions

Your Insight Factory contact, or deployments@insightfactory.ai.

Please do not open issues here; this repository is a distribution point, not a support channel.

About

Setup files for deploying Insight Factory into your own AWS accounts.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors