API Authentication
PiVirt APIs support multiple secure authentication methods depending on the protocol, deployment model, and calling service.
ConnectRPC & gRPC Authentication
Section titled “ConnectRPC & gRPC Authentication”mTLS (Mutual TLS)
Section titled “mTLS (Mutual TLS)”# Using client certificatesgrpcurl \ -cert ~/.config/pvcli/client.crt \ -key ~/.config/pvcli/client.key \ -cacert ~/.config/pvcli/ca.crt \ agent.pilab.hu:8443 \ pivirt.vm.v1.VMService/ListVMsPiTrust mTLS
Section titled “PiTrust mTLS”# Using PiTrust issued client certificatesgrpcurl \ -cert /etc/pivirt/certs/agent-client.crt \ -key /etc/pivirt/certs/agent-client.key \ -cacert /etc/pivirt/certs/ca-chain.pem \ agent.pilab.hu:8443 \ pivirt.vm.v1.VMService/ListVMsBearer Token
Section titled “Bearer Token”# Using JWT tokengrpcurl \ -H "authorization: Bearer $TOKEN" \ -insecure \ agent.pilab.hu:8443 \ pivirt.vm.v1.VMService/ListVMsREST/HTTP Authentication
Section titled “REST/HTTP Authentication”Bearer Token
Section titled “Bearer Token”# Using JWT tokencurl -H "Authorization: Bearer $TOKEN" \ https://agent.pilab.hu:8443/api/v1/vmsAPI Key
Section titled “API Key”# Using API keycurl -H "X-API-Key: $API_KEY" \ https://agent.pilab.hu:8443/api/v1/vmsBasic Authentication
Section titled “Basic Authentication”# Using username/password (not recommended for production)curl -u "admin:password" \ https://agent.pilab.hu:8443/api/v1/vmsConsole & WebSocket Routes
Section titled “Console & WebSocket Routes”The director’s console, screenshot and realtime routes are WebSocket (or binary) endpoints outside /api/v1, and they require the same access token as every other call:
| Route | Purpose |
|---|---|
GET /api/terminals/{vmId} |
Serial console (xterm) |
GET /api/terminals/{vmId}/vnc |
VNC (noVNC) |
GET /api/screenshot/{vmId} |
Framebuffer screenshot |
GET /api/realtime |
Cluster event stream |
A browser cannot set an Authorization header on a WebSocket upgrade, so these routes accept the token either as a bearer header or as a token query parameter:
# Header (non-browser clients)websocat -H "Authorization: Bearer $TOKEN" wss://director.pilab.hu/api/terminals/$VM_ID/vnc
# Query parameter (browsers)wss://director.pilab.hu/api/terminals/$VM_ID/vnc?token=$TOKENA present-but-malformed Authorization header is rejected outright; it does not fall back to the query parameter. Missing or invalid tokens return 401 with code: missing_token or code: invalid_token.
Scope of this check. The token proves who is connecting (PIVIRT-181), and the handler then reads the VM through the caller’s tenant namespaces (PIVIRT-182): a VM the caller has no binding for returns
404. The permanent mechanism is a short-lived, single-VM console ticket minted by the GraphQL API (PIVIRT-187), which will retire the query-parameter form.
Tenant-scoped ConnectRPC on the director
Section titled “Tenant-scoped ConnectRPC on the director”The director’s organisation API (pilab.cli.v1.AdminService, what pvcli org uses) authenticates with the same bearer token and resolves the caller’s RoleBindings before any resolver runs. A missing or invalid token is Unauthenticated; a valid token with no bindings sees nothing — every namespaced call reads as NotFound. See Multi-Tenancy.
Token Management
Section titled “Token Management”Obtain Token
Section titled “Obtain Token”# OIDC loginpvcli auth login --oidc
# Get tokenpvcli auth token getRefresh Token
Section titled “Refresh Token”# Refresh tokenpvcli auth refreshToken Introspection
Section titled “Token Introspection”# Inspect tokenpvcli auth token inspectService Account Authentication
Section titled “Service Account Authentication”Create Service Account
Section titled “Create Service Account”pvcli auth serviceaccount create \ --name "ci-pipeline" \ --namespace "production" \ --role "operator"Generate API Key
Section titled “Generate API Key”pvcli auth apikey create \ --service-account "ci-pipeline" \ --namespace "production" \ --ttl 30dUse API Key
Section titled “Use API Key”export PIVIRT_API_KEY="pivirt_apikey_..."pvcli vm listAuthentication Flow
Section titled “Authentication Flow”OIDC Flow
Section titled “OIDC Flow”sequenceDiagram
participant User
participant pvcli
participant OIDC as OIDC Provider
participant agent
User->>pvcli: auth login --oidc
pvcli->>OIDC: Authorization request
OIDC-->>User: Login page
User->>OIDC: Credentials
OIDC-->>pvcli: Authorization code
pvcli->>OIDC: Exchange code for token
OIDC-->>pvcli: JWT token
pvcli->>agent: Request with JWT
agent->>agent: Validate JWT
agent-->>pvcli: Response
mTLS Flow
Section titled “mTLS Flow”sequenceDiagram
participant Client
participant agent
Client->>agent: TLS handshake
agent->>Client: Request client certificate
agent->>agent: Verify certificate with PiTrust CA
agent->>agent: Extract Certificate SAN / Subject
agent->>agent: Check RBAC
agent-->>Client: TLS established
Client->>agent: gRPC request
agent-->>Client: gRPC response
Troubleshooting
Section titled “Troubleshooting”Authentication Failures
Section titled “Authentication Failures”# Check token validitypvcli auth status
# Verify certificateopenssl x509 -in ~/.config/pvcli/client.crt -text -noout
# Test connectiongrpcurl -insecure agent.pilab.hu:8443 listCommon Issues
Section titled “Common Issues”| Issue | Resolution |
|---|---|
| Token expired | Refresh token: pvcli auth refresh |
| Certificate expired | Regenerate certificate |
| Invalid credentials | Check username/password |
| Permission denied | Check RBAC policy |