Admin API: JIT-elevated SSH endpoint - #5006
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a new admin RP endpoint to mint short-lived, JIT-elevated SSH credentials that are consumed by the existing portal SSH reverse proxy via a persisted PortalDocument (TTL=60s) in Cosmos.
Changes:
- Adds
POST /admin/{resourceID}/ssh/newelevatedand wires it into the authenticated admin routes. - Loads/pins the portal SSH host public key once at frontend startup from the portal Key Vault, returning 503 on endpoint usage if unavailable.
- Adds unit tests covering success/error paths for the new SSH minting endpoint.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| pkg/frontend/frontend.go | Loads portal SSH host public key at startup and registers the new admin SSH route. |
| pkg/frontend/admin_openshiftcluster_ssh.go | Implements the SSH credential minting handler and Key Vault host key loader. |
| pkg/frontend/admin_openshiftcluster_ssh_test.go | Adds unit coverage for the new /ssh/newelevated admin endpoint. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Pushed 6f9814e addressing the review feedback:
Unit tests updated accordingly (added cluster-not-found 404 and missing-identity 400 cases); all 9 subtests green locally. |
Adds an admin RP endpoint that mints per-request SSH credentials for the
portal binary's SSH reverse proxy:
POST /admin/{resourceID}/ssh/newelevated
The response body mirrors the portal binary's ssh.New response
byte-for-byte ({command, password} JSON), so tooling that consumes
either endpoint sees the same shape. The RP writes a PortalDocument
with Portal.SSH{Master} and a 60s TTL; the portal binary's SSH
PasswordCallback then authorises the follow-up TCP connect against
that stored document.
Elevation is JIT-gated by the ACIS manifest that fronts /newelevated
(same pattern as /kubeconfig/newelevated added in PR #4949). The RP
does NOT do an in-process AAD group check.
Before minting, the handler confirms the target cluster document exists
(404 otherwise, mirroring the kubeconfig endpoint) and validates the
caller-identity local-part against a shell-safe character set (400
otherwise), so a typo'd resource ID or a malformed identity can't leave
a stray PortalDocument or inject into the returned command.
The portal SSH host public key is loaded once at frontend startup from
the portal keyvault (secret "portal-sshkey", RSA PKCS#1). On failure
the endpoint returns 503 and RP still starts.
Jira: ARO-26233
Signed-off-by: Richard Rodriguez <rckarod@gmail.com>
6f369a7 to
fa002cb
Compare
|
Re: the 3 failing checks — all pre-existing, not from this PR.
This is tracked and fixed by #5007 ("Fix npm audit CI failure"), which bumps the vulnerable deps and edits This PR touches only 3 Go files and is green on every code gate: |
Which issue this PR addresses:
Fixes ARO-26233 — https://redhat.atlassian.net/browse/ARO-26233
What this PR does / why we need it:
Adds an admin RP endpoint
POST /admin/{resourceID}/ssh/newelevatedthat mintsper-request SSH credentials for the portal binary's SSH reverse proxy. The
response mirrors the portal binary's
ssh.Newresponse byte-for-byte(
{command, password}JSON), and the RP writes aPortalDocumentwithPortal.SSH{Master}and a 60s TTL; the portal binary's SSHPasswordCallbackthen authorises the follow-up TCP connect against that stored document.
Elevation is JIT-gated by the ACIS manifest that fronts
/newelevated(samepattern as
/kubeconfig/newelevated, #4949); the RP does not do anin-process AAD group check. This gives SREs SSH parity with the portal UI via
Geneva Actions. The portal SSH host public key is loaded once at frontend
startup from the portal keyvault (secret
portal-sshkey, RSA PKCS#1); onfailure the endpoint returns 503 and the RP still starts.
Test plan for issue:
TestAdminOpenShiftClusterSSHNewElevated— 8 subtests coveringmaster 0/1/2, missing host key → 503, wrong Content-Type → 415, master out of
range → 400, and Cosmos write failure → 500.
{command, password};PortalDocumentwritten to Cosmos (ttl=60,portal.ssh.master,authenticatedunset); IfxAuditadminOpevent = Success; password is notlogged; portal SSH host key loaded from keyvault.
unchanged portal SSH reverse proxy (
pkg/portal/ssh) and yields a realinteractive shell on
master-0.Is there any documentation that needs to be updated for this PR?
No — this mirrors the existing portal SSH flow (same
PortalDocumentshape, sameproxy consumer); there is no new operator-facing doc surface. Tech-debt/N-A.
How do you know this will function as expected in production?
PortalDocumentshape the portal SSH proxyalready consumes, so the data path is exercised by existing, unchanged code.
adminOpevent for the admin audit trail.starts), invalid
master→ 400, Cosmos write failure → 500. The SSH bearerpassword is never written to logs.
Authoring assisted by GitHub Copilot.