# SSH Access for Operators How to get an SSH certificate from the CCAT step-ca and connect to the input nodes. After setup your daily workflow is just `ssh ` — the certificate renews itself when it expires. **Audience:** members of the `ccatobs/datacenter` GitHub team. Anyone else is rejected at the OAuth step by design. **Time:** ~5 minutes the first time, then never again. ## Prerequisites - Member of the `ccatobs/datacenter` GitHub team. - A web browser on the machine you SSH from (the OAuth flow opens a browser tab). - `step-cli` installed: ```bash # Ubuntu/Debian wget https://dl.smallstep.com/gh-release/cli/docs-cli-install/v0.28.5/step-cli_0.28.5_amd64.deb && sudo dpkg -i step-cli_0.28.5_amd64.deb # macOS brew install step ``` ## Set up (one command) From a clone of `system-integration` with the `ccat` CLI installed (`pip install -e .`): ```bash ccat ssh setup ``` That runs the full onboarding: bootstrap the CCAT root, issue your first cert, install the renewal helper, and write an `~/.ssh/config` block that auto-renews on every connection. Safe to re-run; each step is skipped if already done. Override the principal with `--principal ` if your Linux username is not the principal you want on the cert (default: `id -un`). Verify: ```bash ccat ssh status ssh -v input-a-staging 2>&1 | grep -iE 'offering|accepted' ``` You should see the cert offered and accepted. If it expired, a browser tab opens for OAuth (~3 seconds), then the connection proceeds. ## Daily use - **Cert valid:** `ssh ` connects instantly. - **Cert expired:** `ssh ` opens a browser tab for GitHub OAuth, then connects. The browser is your awareness signal. - **CA down (Tier 1 admin with Nitrokey):** the cert is skipped, the Nitrokey takes over, dongle blinks, you tap, you're in. - **CA down (Tier 2 staff, no hardware fallback):** SSH fails with "Permission denied". Contact an admin — this is the intended failure mode. ## Manual setup (without the `ccat` CLI) If you can't or don't want to install the CLI, the equivalent manual steps are documented in the dedicated client-onboarding how-to: {doc}`ca-client-onboarding`. They are: `step ca bootstrap`, `step ssh certificate`, install the `step-ssh-renew-ccat` helper, add the `Match exec` block to `~/.ssh/config`. The CA URL and fingerprint are pinned in `src/ccat_dc/_constants.py` (`CA_URL`, `CA_FINGERPRINT`). ## Troubleshooting **Browser opens but Dex says "access denied"** — you are not in the `ccatobs/datacenter` GitHub team. Ask a team maintainer to add you at . **`x509: certificate signed by unknown authority` after bootstrap** — the CA vhost is fronted by nginx-proxy; if the proxy is presenting a Let's Encrypt cert instead of the CCAT-rooted one (partial rollout, acme-companion re-issuance, etc.), step-cli rejects it. Verify with `echo | openssl s_client -connect ca.ccat.uni-koeln.de:443 -servername ca.ccat.uni-koeln.de 2>/dev/null | openssl x509 -noout -issuer` — expect `O=CCAT Observatory`. If you see Let's Encrypt instead, an operator needs to re-run the CA-vhost-cert issuance on input-b. Do **not** append the system CA bundle to `~/.step/certs/root_ca.crt` as a workaround; that breaks `step ssh certificate` with `contains more than one PEM encoded block`. **Cert issued but SSH says "Permission denied"** — check the principals on the cert match a Linux username on the target host: ```bash ssh-keygen -L -f ~/.step/ssh/id_ccat-cert.pub | grep Principals ``` For deeper troubleshooting (CA-side issues, provisioner errors, rotation procedures), see {doc}`ca-day-to-day`, {doc}`ca-provisioner-management`, and {doc}`ca-rotation-and-recovery`. ## See also - {doc}`ca-client-onboarding` — the longer manual walkthrough of what `ccat ssh setup` automates. - {doc}`background/ca-architecture` — the full design: why step-ca, why GitHub OIDC, what the cert lifetimes mean. - {doc}`background/ca-provisioner-set` — the provisioner reference table. - {doc}`background/certificate-authority-threat-model` — what the cert auth model defends against and what it does not.