---
title: "Add an OIDC trust rule to a service account."
method: POST
path: "/organizations/{organizationId}/service-accounts/{serviceAccountId}/trust-rules"
tags: ["service-accounts"]
---

# Add an OIDC trust rule to a service account.

`POST /organizations/{organizationId}/service-accounts/{serviceAccountId}/trust-rules`

## Request

- Base URL: `https://api.shorebird.dev/api/v1`
- URL: `https://api.shorebird.dev/api/v1/organizations/{organizationId}/service-accounts/{serviceAccountId}/trust-rules`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer

Lets jobs of one GitHub Actions workflow authenticate as the service
account by exchanging their GitHub OIDC token, so no long-lived key
has to be stored in CI. `github` is the only provider.

The rule matches a token from the named repository and workflow
file, optionally only in one environment and only on matching refs.
The server looks up `repository_owner` on GitHub and stores the
owner's numeric id, which the token's `repository_owner_id` claim
must match, so a deleted owner name registered again by someone else
does not inherit the trust.

Adding a rule requires a plan with OIDC federation (Business or
Enterprise). Requires the `serviceAccountTrustRules.create`
permission, which only the `admin` and `owner` roles hold. Personal
access tokens and federated tokens are refused whatever their role.

## Request body

- CreateServiceAccountTrustRuleRequest: The request body for POST /organizations/{organizationId}/service-accounts/{serviceAccountId}/trust-rules. Unlike `ServiceAccountTrustRule`, the GitHub fields sit at the top level rather than under `github`.
  - `provider` 'github', required: The identity provider whose tokens an OIDC trust rule accepts.
  - `repository_owner` string, required: The login of the GitHub user or organization that owns the repository: letters, digits and hyphens, starting with a letter or digit, at most 39 characters (`^[A-Za-z0-9][A-Za-z0-9-]{0,38}$`). Must exist on GitHub; the server resolves it to its numeric id.
  - `repository_name` string, required: The repository's name: 1 to 100 letters, digits, `.`, `-` or `_` (`^[A-Za-z0-9._-]{1,100}$`), and neither `.` nor `..`.
  - `workflow_path` string, required: The workflow file, directly in `.github/workflows/` and ending `.yml` or `.yaml`, such as `.github/workflows/release.yml`. May not contain `..`.
  - `environment` string, nullable: The GitHub environment the job must run in: 1 to 255 characters, without surrounding spaces. Omitted or null accepts any environment.
  - `ref_pattern` string, nullable: The ref the job must run on, at most 255 characters: exact (`refs/heads/main`), or a prefix ending in a single `*` (`refs/tags/*`), with no other `*` and no whitespace. Omitted or null accepts any ref.

## Response `201`

The newly-added trust rule.

- ServiceAccountTrustRule: An OIDC trust rule: lets a CI workflow authenticate as a service account with a token from the CI provider's identity provider. The provider's own fields are under the provider's name.
  - `id` integer, required: The trust rule's ID.
  - `provider` 'github', required: The identity provider whose tokens an OIDC trust rule accepts.
  - `created_at` string, date-time, required: When the rule was added.
  - `created_by_user_id` integer, nullable, required: The user who added the rule, or null once that user has been deleted.
  - `last_used_at` string, date-time, nullable, required: When a token was last exchanged under the rule, or null if never.
  - `github` GithubTrustRule, required: The GitHub Actions workflow an OIDC trust rule lets in. A token matches when its repository (ignoring case), owner id and workflow file match, and its environment and ref match when the rule names them.
    - `repository_owner` string, required: The repository owner's GitHub login, as entered.
    - `repository_owner_id` integer, required: GitHub's numeric id for the repository owner, resolved when the rule was added and matched against the token's `repository_owner_id` claim.
    - `repository_name` string, required: The repository's name, as entered.
    - `workflow_path` string, required: The workflow file, such as `.github/workflows/release.yml`, matched against the path in the token's `job_workflow_ref` claim.
    - `environment` string, nullable, required: The GitHub environment the job must run in, compared ignoring case, or null for any.
    - `ref_pattern` string, nullable, required: The ref the job must run on: exact (`refs/heads/main`), or a prefix ending in `*` (`refs/tags/*`). Null for any.

## Other responses

- `400`: The organization id is not an integer (`organization_id_malformed`); the service account id is not an integer, the body is not a JSON object, or a field fails validation (`service_account_bad_request`, with the reason in `details`); or no GitHub user or organization has the name in `repository_owner` (`github_owner_not_found`).
- `403`: The organization's plan does not include OIDC federation (`shorebird_plan_insufficient_tier`), the caller lacks the `serviceAccountTrustRules.create` permission, or the caller authenticated with a credential that may never manage service accounts.
- `404`: No such organization or the caller is not a member of it (`organization_membership_guard_error`), or the organization has no service account with that id (`service_account_not_found`).
- `409`: The service account already has a trust rule for the same repository, workflow, environment and ref pattern (`service_account_trust_rule_exists`).
- `424`: A database step failed (`service_account_database_error`), or the organization's billing account could not be looked up to read its plan.
- `503`: GitHub could not be reached, or is rate limiting lookups, so the repository owner could not be resolved (`github_unavailable`). Try again in a few minutes.
- `default`: Standard error response. Emitted for any non-2xx status where a body can be decoded into an [ErrorResponse].

---

[API](https://skmtc.dev/shorebird/apis/shorebird-codepush-api.md) - [All operations](https://skmtc.dev/shorebird/apis/shorebird-codepush-api/llms.txt) - [OpenAPI document](https://skmtc.dev/shorebird/apis/shorebird-codepush-api/revisions/941da8871d10?raw)
