Cordium documentation · Latest

GitHub Actions

This example runs Cordium jobs from GitHub Actions without storing any Cordium or Octelium credential in GitHub. The workflows authenticate as an Octelium WORKLOAD User via the OIDC identity tokens that GitHub issues to every workflow run, which Octelium verifies before granting a short-lived Session (read more here). Two workflows are shown: running the test pipeline of the CI/CD example on every pull request, and dispatching the Claude Code agent when a maintainer labels an issue.

The Workload Identity

First, a Cluster administrator creates an IdentityProvider that trusts GitHub's OIDC tokens, and a WORKLOAD User for the repository's workflows. The User's identities restrict it to the workflows of the main branch, of pull requests and of issue events of the acme-corp/payments-api repository:

kind: IdentityProvider metadata: name: github-actions spec: oidcIdentityToken: issuerURL: https://token.actions.githubusercontent.com audience: https://example.com --- kind: User metadata: name: payments-api-ci spec: type: WORKLOAD authentication: identities: - identityProvider: github-actions identifier: repo:acme-corp/payments-api:ref:refs/heads/main - identityProvider: github-actions identifier: repo:acme-corp/payments-api:pull_request authorization: policies: ["cordium-users"]

The cordium-users Policy grants access to the Cordium API (read more here). Then, a Space admin adds payments-api-ci as a USER Member of the payments Space from the Members tab of the Space's page in the web portal, which lets it create Workspaces from the Space's Templates (read more here).

note

The identifier is matched against the sub claim of GitHub's OIDC token, whose format depends on the event that triggered the workflow (e.g. repo:<ORG>/<REPO>:ref:refs/heads/<BRANCH> or repo:<ORG>/<REPO>:pull_request). Workflows triggered by issue events use the default branch, i.e. repo:acme-corp/payments-api:ref:refs/heads/main.

Running Tests on Pull Requests

The following workflow runs the ci_run.py script of the CI/CD example, committed in the repository as .github/cordium/ci_run.py, for every pull request. The Python SDK reads the OIDC token from the OCTELIUM_ASSERTION environment variable:

name: Cordium CI on: pull_request: permissions: id-token: write contents: read jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.13" - run: pip install cordium-sdk - name: Get an OIDC token for Octelium run: | TOKEN="$(curl -fsSL -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=https://example.com" | jq -r .value)" echo "::add-mask::$TOKEN" echo "OCTELIUM_ASSERTION=$TOKEN" >> "$GITHUB_ENV" - name: Test in Cordium env: OCTELIUM_DOMAIN: example.com run: python .github/cordium/ci_run.py "${{ github.event.pull_request.head.sha }}"

The job's log shows the output of every step that runs in the Cordium Workspace, and the job fails if any of them fails. Note that GitHub does not issue OIDC tokens to the workflows of pull requests from forks.

Dispatching an AI Agent from Issues

The following workflow starts a run of the Claude Code agent whenever a maintainer adds the agent label to an issue. It uses the cordium CLI, which fetches GitHub's OIDC token by itself when OCTELIUM_AUTH_ASSERTION is set to github-actions (read more here):

name: Cordium agent on: issues: types: [labeled] permissions: id-token: write issues: write jobs: dispatch: if: github.event.label.name == 'agent' runs-on: ubuntu-latest env: OCTELIUM_DOMAIN: example.com OCTELIUM_AUTH_ASSERTION: github-actions:audience=https://example.com GH_TOKEN: ${{ github.token }} ISSUE_NUMBER: ${{ github.event.issue.number }} ISSUE_TITLE: ${{ github.event.issue.title }} ISSUE_BODY: ${{ github.event.issue.body }} steps: - name: Install the Cordium CLI run: curl -fsSL https://octelium.com/install-cordium.sh | bash - name: Start the agent run: | TASK="$(printf 'Fix #%s: %s\n\n%s' "$ISSUE_NUMBER" "$ISSUE_TITLE" "$ISSUE_BODY")" cordium create ws --template claude-agent.payments.cordium --ephemeral --start \ --var TASK="$TASK" gh issue comment "$ISSUE_NUMBER" --repo "$GITHUB_REPOSITORY" \ --body "A Cordium agent is working on this issue and will open a draft pull request."

The issue's content is passed to the workflow's script via environment variables rather than being expanded into the script itself, which keeps it from being interpreted by the shell. The agent's Workspace then runs as described in the Claude Code example, with its own secretless access to the Anthropic API and GitHub.

note

The issue's content is untrusted input for the agent: anyone who can open an issue can attempt a prompt injection. This is why the workflow only runs when a maintainer adds the label, and why the agent's Workspace holds no credentials and can only reach one repository through Octelium. Protect your main branch with branch protection rules so that the agent's changes always go through a reviewed pull request, and treat them like those of any external contributor.