Authentication
Repository checkout authentication for Workflows — why JobToken is recommended, how it compares to SSH keys, and how to migrate
The first Step in most Workflows is a repository checkout. CollabOps recommends authenticating that checkout with JobToken. This page explains what JobToken is, why it is the recommended path, and how to migrate existing SSH-key-based workflows.
TL;DR — write repo-url as https://.... JobToken is injected automatically; no key registration or rotation is required.
What JobToken is
JobToken is a short-lived credential that the platform issues and injects when a Job starts and revokes the moment the Job finishes. Its key properties:
Ephemeral — valid only inside the Job runtime; automatically invalidated when the Job ends.
Scoped — limited to read access on the repository the Job belongs to. It cannot reach other repositories or workspaces.
System-issued — not tied to any individual user. Pipelines keep working when team members leave or have their permissions changed.
Auditable — every access is recorded with the Job context (Run ID, repository, trigger event).
Zero setup — no key to generate, register, or rotate. collabops/checkout@v2 uses it automatically when given an HTTPS URL.
Why JobToken is the recommended path
Registering a personal SSH private key as a workspace variable and using it for checkout is a common habit, but it carries the following risks:
| Aspect | JobToken (HTTPS) | Personal SSH key |
|---|---|---|
| Lifetime | Revoked when the Job ends | Valid until manually revoked |
| Issuer | Platform (system) | Individual account |
| Permission scope | Read on the Job's repository | Whatever the key holder can do |
| Impact when owner leaves | None | Pipelines break |
| Leak response | Auto-invalidated on next Job | Manual revoke + re-register everywhere |
| Audit trail | Per-Job, automatic | Per-key, hard to attribute |
| Initial setup | None | Generate key → base64 encode → register variable → register public key on repository |
| Rotation | Automatic | Manual, ongoing operations cost |
The biggest operational liability of a personal key is that it is bound to one person. When that person leaves the team or has their permissions revoked, every workflow that references the same variable stops working at once.
Recommended pattern
Write repo-url with the HTTPS scheme. No additional authentication input is required.
jobs:
build:
steps:
# JobToken is injected automatically — no ssh-key, no variable to register
- name: checkout
uses: "collabops/checkout@v2"
with:
repo-url: "https://<collabops-host>/<workspace>/<repository>.git"
- name: build
run: npm ci && npm run build
image: node:18Fill in <collabops-host>, <workspace>, and <repository> for your environment. There is no need to reference the token via an expression.
When SSH keys are still appropriate
Use the ssh-key input only in the following limited cases:
Checking out an external (third-party) Git host.
On-premise environments where network policy blocks HTTPS and only allows SSH.
Cloning an additional repository that lies outside the JobToken scope.
Even in those cases, prefer a per-repository deploy key over a personal account key. Deploy keys are scoped to a single repository, so the blast radius on leak is small.
Do not register a personal SSH private key as a workspace variable. The key holder's full repository permissions are inherited by every workflow that uses it.
Migration
Migrating an existing SSH-key-based checkout to JobToken:
Before
# ❌ Personal SSH key — permission tied to an individual, ongoing key management
jobs:
build:
steps:
- name: checkout
uses: "collabops/checkout@v2"
with:
repo-url: "git@<collabops-host>:<workspace>/<repository>.git"
ssh-key: "${{ secrets.GIT_SSH_KEY }}"After
# ✅ JobToken — switch the URL to https and drop every auth input
jobs:
build:
steps:
- name: checkout
uses: "collabops/checkout@v2"
with:
repo-url: "https://<collabops-host>/<workspace>/<repository>.git"Checklist
Change repo-url from git@... / ssh://... to https://....
Remove the with.ssh-key input.
Verify other Steps do not reference the SSH key (e.g. git submodule, private package install).
Once the Workflow runs cleanly, revoke the SSH key in the workspace variables and remove the matching public key from the repository.
FAQ
Can I reference the JobToken directly in an expression?
You don't need to. collabops/checkout@v2 uses it internally. In the rare cases where a Step has to call git directly, the same credential is already configured inside the Job container, so no extra wiring is needed.
Can I push with the JobToken?
JobToken is read-only. If a Workflow needs to commit and push, issue a separate workspace-level automation account credential and use that instead.
What about authentication for private npm / PyPI / other registries?
External registries are outside the JobToken scope. Register a separate token in workspace secrets and reference it like $\{\{ secrets.NPM_TOKEN \}\}. For Docker registry authentication use the docker-login template (gcloud-docker-auth for GCP, aws-ecr-auth for AWS ECR).
Registering an SSH key
The ssh-key input of collabops/checkout expects a base64-encoded OpenSSH private key. This is the official format, not a temporary workaround.
SSH keys fail authentication if even a single newline or whitespace character is corrupted. Pasting a multi-line value into a Secret input always carries that risk, so we require a single-line base64 string to eliminate it entirely.
Encoding commands by OS
# macOS — copy to clipboard
cat /path/to/private_key | base64 | pbcopy
# Linux — single-line stdout
cat /path/to/private_key | base64 -w0
# Windows PowerShell — copy to clipboard
[Convert]::ToBase64String([IO.File]::ReadAllBytes("$env:USERPROFILE\.ssh\id_rsa")) | Set-ClipboardThe result must be a single line with no newlines. Register that string as the Secret value. WSL environments can use the Linux command as-is.
collabops/ssh-exec and collabops/scp-upload accept the same base64 input. For compatibility they still recognize raw OpenSSH input, but standardizing every SSH key Secret on base64 reduces user error.
Troubleshooting auth failures
If decoding fails or the decoded content is not an OpenSSH private key, the workflow log prints the same encoding commands inline. Check the following.
The encoded value is a single line with no newlines
Decoded content starts with a header such as -----BEGIN OPENSSH PRIVATE KEY-----
The matching public key is registered on the repository side (or as a Deploy Key)