# Security

> What the SquidCI stack creates in your AWS account, the one permission it opens to SquidCI, what SquidCI holds and what it never sees, and how jobs are isolated.

Builds run in your AWS account, so the question a security team asks is what
SquidCI gets there. In short: **no standing access**. There is no
cross-account role, nothing SquidCI can assume, and no credential of ours in
your account. One thing is opened to SquidCI, and it can send instructions,
not read anything.

## What the stack creates

You create the stack yourself from the **aws** page, and can read its
template first: the **or create the stack yourself** section links it. It
creates, in the account and region you chose:

- **Roles** for its own parts, each trusted only to the AWS service that runs
  it: the worker instances, the CloudFormation service that builds worker
  groups (with a ceiling on what those stacks may create), and the functions
  that apply worker groups, report on them, answer SquidCI's challenges and
  update the plane's code.
- **A task role**, `squidci-<slug>-task`, which each job runs as — created
  with no permissions; it gains the right to assume your target accounts'
  `ci` roles as you add them.
- **A KMS signing key** the plane proves its identity with. Its key policy
  names your account only: SquidCI cannot use, disable or delete it, and the
  private half never leaves KMS.
- **An EventBridge bus**, `squidci-<slug>`, which SquidCI sends to.
- **Worker groups**, later, as child stacks, within the ceiling above.

The code it runs is published signed, and every function enforces the
signature: an unsigned or altered zip is refused, by the plane's updater and
by AWS alike.

## The one thing opened to SquidCI

```yaml
Principal: arn:aws:iam::<SquidCI's account>:root
Action:    events:PutEvents
Resource:  the squidci-<slug> event bus
```

One action, on one bus, from one account: how SquidCI sends the daily
heartbeat challenge and worker group instructions. Nothing can be read
through it. A worker group change it asks for is applied by your own
function, within the ceiling your stack set.

## What leaves your account

- **To SquidCI**: worker and job status, heartbeats, and **job logs** — what
  your steps print. SquidCI keeps logs for 30 days and serves them only
  through short-lived signed links. Build output often contains things nobody
  meant to print, so treat it as you would any log store: don't echo secrets.
- **Values a job exports** for other jobs: short strings, shown with the job.
- **From SquidCI**: templates, the plane's code and the worker agent, from a
  public read-only bucket, and SquidCI's runner image from ECR Public. Your
  account reaches out for these; nothing is pushed in.

Your workers call two SquidCI hosts over HTTPS: the API of your organization's
region and `auth.squidci.cloud`, to exchange a signed assertion for a token.
They need outbound internet; they accept no inbound connections.

## What SquidCI never sees

- **Your source code.** The GitHub App mints short-lived tokens that your
  workers clone with, in your account. SquidCI reads only what GitHub tells it
  about changes, and your pipeline file.
- **Your secrets and build output**, beyond what is printed to the log.
- **Anything in your AWS account**: there is no permission to read it.

## Jobs

- **Each job runs in its own container** under Sysbox, unprivileged, so it can
  run Docker without being given the host. Jobs cannot reach the instance's
  own credentials: the metadata service refuses them a token.
- **A job's AWS credentials** are the task role's, held by a session policy to
  exactly the target accounts its pipeline file names. See
  [AWS access for jobs](/docs/pipelines/aws/).
- **Pull requests get no AWS access at all**, and run only checks, tests and
  builds: until merged, the pipeline file is its author's. Pull requests from
  forks are not built.

## Disconnecting

**disconnect** on the **aws** page makes SquidCI forget the account and stop
sending it work at once. It removes nothing from AWS: delete the SquidCI stack
in CloudFormation, which removes its worker groups, roles and key.
