Skip to content

Allocation Project SSH Access Grants

Status: implemented foundation
Owner domains: Access, Workloads, Provisioning

Problem

Replacing an allocation's SSH key set only solves the owner's key lifecycle. It does not support team handoff: another project member must be able to access a live allocation with their own public key, without the allocation owner sharing a private key or replacing the owner's key set.

Model

An allocation access grant is an explicit project-scoped permission for one project member to add one of their personal SSH public keys to the allocation runtime account.

  • The grant is scoped to one allocation and one project.
  • The grantee must already be a member of the allocation's project.
  • The SSH key must be a personal key owned by the grantee.
  • Project-scoped automation keys are not valid grant keys.
  • The current runtime model installs all approved keys into the allocation's existing username_on_node; it does not create per-grantee Unix users yet.

Authorization

Create or update access:

  • Allocation owner.
  • Project owner/admin.
  • Tenant owner/admin for the allocation's tenant.
  • Platform admin.

Revoke access:

  • Same actors as create.
  • The grantee may revoke their own grant.

Service accounts are intentionally denied for human SSH grants. They may manage project-scoped automation credentials through the project access-credential surface instead.

Runtime Sync

For active allocations, each grant create/update/revoke queues allocation.install_authorized_keys on the node agent. The task payload is the complete desired key set:

  1. allocation owner/project keys from allocation_ssh_public_keys;
  2. active project-member grants from allocation_access_grants.

This prevents a later owner key replacement from dropping team-member grants.

For requested/provisioning allocations, active grants are read during provisioning and included in the initial authorized_keys material.

Audit

Every mutation writes audit_logs:

  • allocation.access_grant.create
  • allocation.access_grant.revoke

Audit metadata includes allocation, project, grantee, key, and runtime sync task information when a live node sync was queued.

API Surface

  • GET /api/v1/allocations/{allocation_id}/access-grants
  • POST /api/v1/allocations/{allocation_id}/access-grants
  • DELETE /api/v1/allocations/{allocation_id}/access-grants/{grant_id}

The API remains under /api/v1 while V3 UI migration is in progress because this is a control-plane capability, not a visual-only route.