# AWS access for jobs

> How a job reaches the AWS accounts it deploys to — target AWS accounts, the ci role and its trust policy, profiles and regions in the pipeline file, and what pull requests get.

A job reaches an AWS account only when its pipeline file says so, and only
the accounts it names. Three pieces line up:

1. **A target AWS account**, added to your execution plane: a profile name
   and an account id.
2. **A role named `ci`** in that account, trusting your plane.
3. **`aws` in the pipeline file**, naming the profiles a component's jobs — or
   an environment's deploys — may use.

## 1. Add a target AWS account

On the **aws** page, under your connected account, choose **+ add a target AWS
account**:

- **profile**: the name jobs use for it — `dev`, `prod`, `data`. Lower-case
  letters, digits and hyphens, starting with a letter; not `default`.
- **account**: the twelve-digit account id.

Adding one changes nothing in that account. It lets your plane's task role
ask to assume the account's `ci` role; the role still has to agree.

## 2. Create the ci role in the target account

In each target account, a role named exactly `ci`, trusting the account your
execution plane is in — the jobs' own role there is tagged
`squidci:role = task`:

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "AWS": "arn:aws:iam::<PLANE_ACCOUNT_ID>:root" },
      "Action": ["sts:AssumeRole", "sts:TagSession"],
      "Condition": {
        "StringEquals": { "aws:PrincipalTag/squidci:role": "task" }
      }
    }
  ]
}
```

`sts:TagSession` is required: each job's session carries tags a policy can
read — `squidci:repository` (`owner/name`), `squidci:commit` and
`squidci:job`. To let only one repository's jobs in, add to the condition:

```json
"aws:PrincipalTag/squidci:repository": "your-org/your-repo"
```

Give the role what your deploys need. A CI role commonly has broad rights in
the account it deploys; the trust policy and the pipeline file are what
narrow who becomes it. Sessions last an hour and the SDKs refresh them, so
long jobs are fine.

## 3. Name it in the pipeline file

```yaml
# yaml-language-server: $schema=https://squidci.com/schema/pipelines.json
infra:
  aws:
    profile: prod          # what plain `aws` uses
    profiles: [prod, data] # everything the jobs may use
    region: eu-west-2      # where they work; the plane's region otherwise
  run:
    - aws sts get-caller-identity                 # as prod's ci role
    - aws --profile data s3 ls                    # as data's ci role
```

Each profile becomes an AWS CLI profile of that name, chaining from the job's
own credentials to that account's `ci` role, so every SDK and tool that reads
AWS profiles works: `aws --profile data …`, `AWS_PROFILE=data cdk deploy`.
`profile` is set as `AWS_PROFILE`, so plain `aws` means it.

**It is enforced, not a convenience.** A job's credentials can assume only the
`ci` roles of the profiles its component names, whatever a step does with
them. A profile no execution plane of yours has makes the file invalid; a
component whose profiles no single plane has all of waits for one that does.

## Deploys use their environment's

A deploy gets its **environment's** `aws`, in place of the component's —
wholly, region included:

```yaml
environments:
  dev:
    aws: {profile: dev, region: eu-west-1}
  prod:
    aws: {profile: prod, region: eu-west-2}
    after: dev

api:
  aws: {profile: tools}      # check, test, build: the tools account
  build:
    - make build
  deploy:
    - make deploy            # dev's account in dev, prod's in prod
```

## Regions

`region` sets `AWS_REGION` and `AWS_DEFAULT_REGION` in the job. Without it, a
job's region is your execution plane's. Tools that take the region from the
environment — most of them — then work in the right place. SquidCI's own work
for the job, its cache and artifacts, stays in the plane's region whatever
the job's is.

## What a job gets without aws

No target account at all. Its own credentials reach only its run's artifacts
in your plane, and the plane's staging repository for images.

## Pull requests

Pull requests ignore `aws` entirely, and their jobs get no AWS credentials:
until someone merges it, the pipeline file is its author's, and honouring
its `aws` would let anyone who can open a pull request assume your roles.
