CLI guide
GitHub

Service accounts

A service account is an account for software, such as a GitHub Actions workflow or a script with an API key. It has an owner: you, or an organization that you own or maintain. source.coop must first let that account own service accounts.

A service account's ID is the owner's ID, then --, then its own name: my-org--nightly-sync. AWS tools use this ID: role-to-assume: arn:aws:iam::my-org--nightly-sync:role/FullAccess.

source-coop service-account shows a service account as the web UI does: what it is, how it signs in, and the products it can use.

List and view

# my-org's service accounts (yours, with no owner)
source-coop service-account list my-org

# print directly, not in the pager
source-coop service-account list my-org --no-pager

# move through them full screen (keys as for products)
source-coop service-account list my-org -i

# --json adds `trusts`, `keys` and `memberships`
source-coop service-account view my-org--nightly-sync

# open its page in the browser
source-coop service-account view my-org--nightly-sync -w
service-account list: an owner's service accounts, then as --json

view shows who the service account is, how it signs in and the products it can reach. --json adds trusts, keys and memberships.

service-account view: who it is, how it signs in, what it can reach; --json adds trusts and memberships

list -i uses the same keys as product list -i. On a service account's screen, e edits it and d deletes it.

service-account list -i: open one, go back, delete one from its screen

Create

# asks for all values, as the web form does
source-coop service-account create

# all values from flags
source-coop service-account create my-org--nightly-sync --name "Nightly sync" \
    --github my-org/data --branch main --access my-org/my-data=write

create takes values as flags, as a JSON object with --from-file, or both:

At a terminal, create asks for the missing values: the owner, the name, the ID (made from the name), workflows and an API key, and products. Then it shows all values, with the condition that each workflow must match, and asks you to confirm.

service-account create with prompts

If create issues a key, it gives you the key as sign-in add does. But stdout gets the account's ID, not the key. To keep the key, use --out or --json.

create and edit print the service account's ID on stdout. Thus id=$(source-coop service-account create …) works. Going back, drafts, the sign-in check and --yes work as for products.

service-account create from flags, with --json

Edit

# rename it
source-coop service-account edit my-org--nightly-sync --name "Nightly sync"

# a form of its name and products
source-coop service-account edit my-org--nightly-sync

# --enable lets it sign in again
source-coop service-account edit my-org--nightly-sync --disable

--disable stops all sign-ins as the service account. It keeps its sign-ins and products. --enable lets its workflows and its keys that are not revoked sign in again.

With no flags, edit opens a form of its name and products (see Access to products).

service-account edit: --disable, --enable, then a rename in the edit form

Delete

# asks you to type its ID
source-coop service-account delete my-org--nightly-sync

delete removes the service account, its sign-ins and its access to products. Type its ID to confirm, or use --yes.

service-account delete: typed confirmation, then --yes --json

Access to products

A service account can read, or read and write, its owner's products. Each grant is a usual membership of the product.

source-coop service-account edit my-org--nightly-sync --access my-org/my-data=write --access my-org/old-data=none

If the product already has that role, or has no access to remove, nothing changes. Thus you can run an edit two times safely.

With no flags, edit opens a full-screen form with Name, then the products under Can reach, each with its role:

--disable and --enable are flags only.

service-account edit --access, then the edit form: take a product away, grant another

Sign-ins

A service account signs in in one of two ways:

# trust runs on a branch
source-coop service-account sign-in add my-org--nightly-sync --github my-org/data --branch main

# trust runs in a GitHub environment
source-coop service-account sign-in add my-org--nightly-sync --github my-org/data --environment production

# trust a subject as it is
source-coop service-account sign-in add my-org--nightly-sync --subject repo:my-org/data:ref:refs/tags/v1

# remove a trust by its subject
source-coop service-account sign-in remove my-org--nightly-sync repo:my-org/data:ref:refs/heads/main

# select a sign-in
source-coop service-account sign-in remove my-org--nightly-sync -i

The CLI asks GitHub how the repository's tokens name it, as the web UI does. Some repositories use IDs (owner@123/repo@456), which never match owner/repo. For a private repository, set GH_TOKEN (or GITHUB_TOKEN). If GitHub does not answer, the CLI tells you how to find the name.

At a terminal, without these flags, sign-in add asks for the repository and the runs to trust. Then it shows the condition and asks you to confirm.

sign-in add with prompts and from flags, sign-in remove -i, sign-in revoke-key

API keys are for places without GitHub's tokens, such as a cron job on a cluster.

# issue a key that expires in a year, and save it to a file
source-coop service-account sign-in add my-org--nightly-sync --key "HPC cron job" --expires 1y --out ~/.source-coop/nightly.key

# piped: only the key on stdout
key=$(source-coop service-account sign-in add my-org--nightly-sync --key "HPC cron job")

# a new expiry, from now
source-coop service-account sign-in edit my-org--nightly-sync key:a1B2c3 --expires never

# revoke it; asks you to type key:a1B2c3
source-coop service-account sign-in remove my-org--nightly-sync key:a1B2c3

The CLI shows a key one time only, when it issues the key:

view lists each key by its label and its last six characters, such as key:a1B2c3. sign-in edit and sign-in remove use this name. view also shows when the key was last used and when it expires. It shows revoked and expired keys dimmed. You cannot restore a revoked key.

At a terminal, without flags, sign-in add asks if you want a workflow or a key. sign-in edit -i and sign-in remove -i let you select one.

sign-in add --key --out, sign-in edit -i and sign-in remove: issue an API key, give it a new expiry, then revoke it

If a key leaks, anyone with the key can revoke it, without signing in. The command reads the key from stdin, so the key is not in your shell history:

source-coop service-account sign-in revoke-key < leaked-key-file

Use a service account

Workflows and scripts sign in with standard AWS tools, not with this CLI. usage prints what they need, as the web UI does:

# a workflow that uses aws-actions/configure-aws-credentials
source-coop service-account usage my-org--nightly-sync --subject repo:my-org/data:ref:refs/heads/main \
    > .github/workflows/source-coop.yml

# the AWS_* variables for a key in a file
source-coop service-account usage my-org--nightly-sync --key

At a terminal, without --subject or --key, usage asks which sign-in to show.

service-account usage: pick a sign-in for its workflow, then --key