# Authentication {#bot-authentication}

A [bot](/docs/c/bot/index.md) signs in to Shisho Cloud with the `shishoctl` CLI using one of four methods:

| Environment                                              | Recommended method                          |
| -------------------------------------------------------- | ------------------------------------------- |
| GitHub Actions                                           | [GitHub Actions OIDC](#github-actions-oidc) |
| GitLab CI                                                | [GitLab CI OIDC](#gitlab-ci-oidc)           |
| Self-hosted CI/CD or other OIDC-Discovery-compliant IdPs | [Custom OIDC](#custom-oidc)                 |
| Other CI/CD or automation environments                   | [API Key](#api-key)                         |

The three OIDC-based methods rely on a **trust condition**: a rule, configured on the bot, that decides which OIDC ID tokens Shisho Cloud accepts as proof that the caller may sign in as that bot. Trust conditions are more secure than an API key because there's no static secret to store or leak - the identity provider mints a short-lived token for each job, and Shisho Cloud never sees anything but ephemeral credentials.

## API Key {#api-key}

For bot authentication in environments that aren't OIDC-compliant, you can use an API key to access Shisho Cloud from `shishoctl`.

API keys are associated with bots. Therefore, if you have not yet created a bot, you should create one first. Follow these steps:

1. Access the [bots list](https://cloud.shisho.dev/*/settings/bots) page
2. Click the "Add Bot" button to create a new bot

Once created, you can issue an API key by following these steps:

1. Access the [bots list](https://cloud.shisho.dev/*/settings/bots) page.
2. Click on the name of the bot you created to open its detail page.
3. In the API Key tab, click "Create API Key" to create a new API key for the bot.

:::warning Important
API keys are only displayed once at creation time. You cannot retrieve them later, so make sure to save them in a secure location when they are created.
:::

To sign in using an API key, run the following command:

```shell
shishoctl auth signin:bot \
  --bot <Bot ID> \
  --api-key-json "$(cat api-key.json)"
```

The `api-key.json` file must be in the following JSON format:

```json
{
  "api_key": "shisho_apikey_..."
}
```

Alternatively, you can specify the API key directly:

```shell
shishoctl auth signin:bot \
  --bot <Bot ID> \
  --api-key-json '{"api_key":"shisho_apikey_..."}'
```

:::info
The Bot ID is an ID starting with `BT`. After creating a bot on the [bot creation page](https://cloud.shisho.dev/*/settings/bots), you can find it in the URL of the bot's details page.

https://cloud.shisho.dev/{ORGANIZATION_ID}/settings/bots/{BOT_ID}
:::

:::warning Security Best Practices

Like API keys for general SaaS products, if a bot's API key is leaked, data on Shisho Cloud may be compromised. To handle them securely, please keep the following in mind:

- Do not publicly expose API keys. In particular, do not commit them to public repositories such as GitHub.
- When storing API keys in private locations, use the most secure location possible. For example, use GitHub Actions' secret management feature rather than including them directly in a GitHub repository.
- Delete API keys promptly when they are no longer needed.

:::

## GitHub Actions OIDC {#github-actions-oidc}

For jobs running in GitHub Actions, Shisho Cloud authenticates using the OIDC ID token that GitHub issues to each job, so you don't need to store a persistent secret in the repository. Shisho Cloud exchanges that token for short-lived credentials scoped to a specific bot - a pattern similar to [GitHub's own OIDC-based cloud integrations](https://github.blog/changelog/2021-10-27-github-actions-secure-cloud-deployments-with-openid-connect/).

The trust condition for a GitHub Actions bot matches on the **organization and repository name** of the GitHub repository the job runs in. Once the trust condition is saved, any job belonging to that repository can sign in as the bot.

To sign in from a job, request an ID token and run:

```shell
shishoctl auth signin:bot \
  --bot <Bot ID> \
  --expires-in-minutes 60 \
  <<< "$ID_TOKEN"
```

For the full step-by-step setup - creating the bot and trust condition in the console, and wiring up a GitHub Actions workflow - see [Managing Rules with SCM - GitHub](/docs/g/getting-started/deploy-policies-with-git-repositories/github.md).

## GitLab CI OIDC {#gitlab-ci-oidc}

For jobs running in GitLab CI/CD, Shisho Cloud authenticates using the OIDC `ID_TOKEN` that GitLab can issue to a job, so you don't need to register a Shisho Cloud access token as a GitLab CI/CD secret.

The trust condition for a GitLab CI bot matches on the project's **project path** - the part of the project's URL that starts at the top-level group and ends at the project name, e.g. `my-group/my-subgroup/my-project`. Once the trust condition is saved, any job belonging to that project can sign in as the bot.

:::warning
GitLab lets a group, subgroup, or project use a display name that differs from its URL path. Always check the path shown in the project's URL - not its display name - when configuring the trust condition.
:::

To sign in from a job, request an ID token and run:

```shell
shishoctl auth signin:bot \
  --bot ${SHISHOCLOUD_BOT_ID} \
  --expires-in-minutes 60 \
  <<< ${ID_TOKEN}
```

For the full step-by-step setup - creating the bot and trust condition in the console, and wiring up a GitLab CI/CD job - see [Managing Rules with SCM - GitLab](/docs/g/getting-started/deploy-policies-with-git-repositories/gitlab.md).

## Custom OIDC {#custom-oidc}

:::info
Custom OIDC provider support is currently in beta.
Specifications and behavior may change without prior notice.
:::

If your environment isn't GitHub Actions or GitLab CI but can still mint an OIDC ID token - a self-hosted CI/CD system (Jenkins, Buildkite, CircleCI, etc.), another cloud's workload identity federation (e.g. AWS IAM Roles Anywhere, GCP Workload Identity Federation), or any other OIDC-Discovery-compliant identity provider - you can configure a trust condition directly against its issuer. The issuer must serve over `https://` and expose an OIDC Discovery document (`/.well-known/openid-configuration`).

A custom OIDC trust condition takes three required inputs, plus an optional one:

- **Issuer** - the `https://` URL of the ID token's issuer (its `iss` claim).
- **Subject** - the expected value of the ID token's `sub` claim: either an exact string, or an expression where `*` matches any sequence of characters (e.g. `repo:acme/app:*`). A bare `*` is not allowed. Pin it as tightly as your IdP's subject format allows - every wildcard you add widens who can sign in as the bot.
- **Audience** - the value the ID token's `aud` claim must contain. This is mandatory for custom OIDC trust conditions (unlike the GitHub Actions / GitLab CI schemas). We recommend configuring your IdP to issue ID tokens with `https://sts.cloud.shisho.dev` as the audience, so a token minted for Shisho Cloud can't be replayed against another relying party.
- **Claims** (optional) - up to 10 additional conditions on other top-level string claims of the token, each matched the same way as Subject (exact value or `*`-expression). Registered claims (`iss`, `sub`, `aud`, etc.) can't be used here.

:::info Limit

An organization can have **one** custom OIDC trust condition in total, across all of its bots. GitHub Actions and GitLab CI trust conditions are not limited.

If you need more than one, contact support - whether we can accommodate the request depends on your plan.

:::

For example, a trust condition that only accepts ID tokens for tagged, production-environment deployments from a self-hosted IdP might look like this:

| Field    | Value                                               |
| -------- | --------------------------------------------------- |
| Issuer   | `https://idp.example.com`                           |
| Subject  | `repo:acme/app:*`                                   |
| Audience | `https://sts.cloud.shisho.dev`                      |
| Claims   | `environment` = `production`, `ref` = `refs/tags/*` |

Once the trust condition is saved, the CI-side flow is the same as for GitHub Actions or GitLab CI: obtain an ID token from your IdP, then sign in with it:

```shell
shishoctl auth signin:bot \
  --bot <Bot ID> \
  --expires-in-minutes 60 \
  <<< "$ID_TOKEN"
```

:::warning Security Best Practices

- Pin **Subject** as tightly as possible. Every `*` you add widens the set of identities that can sign in as the bot; a Subject of just `*` isn't allowed.
- Configure your IdP to set the **Audience** (`aud`) claim to `https://sts.cloud.shisho.dev`. Trust conditions require this value to be present, and setting it explicitly on the IdP side prevents the same token from being accepted by unrelated services.
- Use **Claims** conditions to pin details your IdP doesn't encode in `sub` (branch, tag, environment, etc.) instead of relying on a broad Subject wildcard alone.

:::
