Kibotos

Data plane

Files, processes, desktops, and service connections go directly to the node that runs the Workspace, without forwarding through ctrl. This page shows how to request a session credential from ctrl, keep it valid, and call the node with it.

Every data-plane call takes two steps:

  1. Request a short-lived session credentialA short-lived credential for the data plane. You request it from ctrl, together with the address of the node that runs the Workspace. from ctrl. The response also gives the address of the node.
  2. Send the request to that address with the credential.

Requesting a session credential

Call DataPlaneSessionService/CreateDataPlaneSession on ctrl for an AVAILABLE Workspace. Every field of the request and the response is listed in DataPlaneSessionService.

  • Give a command ID in metadata.command_id. Replaying the same ID returns the same credential.
  • Request only the scopes your calls need in requested_scopes. The scope each method needs is in Data-plane services.
  • For SERVICE_CONNECT, list the exact targets in service_targets.
  • To keep the credential from reaching a newer execution, set expected_generation to the generationOne run of a Workspace. Every successful start begins a new generation, numbered from 1 upward; the credentials, processes, and connections of the previous generation become invalid. you believe is current. A mismatch returns FAILED_PRECONDITION.

When the request is refused with FAILED_PRECONDITION, observed_workspace in the error details carries the Workspace as it was. Use it to decide whether the execution has ended:

WorkspaceMeaning
generation differs from expected_generation, or the state is STOPPED or DELETEDThis execution has ended, along with its processes and connections
The state is STOPPING, DELETING, FAILED, or UNKNOWN, or still AVAILABLE (for example expired but not yet stopped)The execution may still be running. Ask again later

Credential lifetime

lifetime selects one of two policies:

lifetimeHow long the credential lastsConstraints
Defaultrequested_ttl. The default is 5 minutes and the limit is 15 minutes. 0 means the default. Other values must be whole seconds from 1 second up to the limit; a longer value returns invalid_argumentNone
EXECUTIONBound to the current execution of the Workspace: at most 1 hour, ending at the Workspace's expiration time if that comes firstRequires expected_generation. requested_ttl is not allowed. Capability name workspace.session.execution

Response

The response carries the credential in credential, and in session the address of the node data plane (endpoint), the granted scopes and targets, and the expiration time expires_at. session.generation is the Workspace's generation when the credential was issued: the same value means the same execution, even if endpoint changed. Use session.endpoint as the base URL of every data-plane request.

Warning

Treat credential as a secret. Do not parse it, log it, or put it in a URL. Log session.session_id when you need to correlate requests.

Caching and renewing the credential

When you cache a credential and reuse it across requests:

  • Request a new one once about 80% of the lifetime has passed, minus up to 10% random jitter. Do not wait until only a few seconds remain. The node allows 30 seconds of clock skew, so with a small fixed margin, the node can reject the credential while you still believe it is valid.
  • When the node returns the reason SESSION_EXPIRED, SESSION_REVOKED, or UNAUTHENTICATED, discard the cached credential and request a new one for the next request. Do not retry with the same credential.
  • Do not go by the error code alone. A guest refusing file access and a credential missing a scope also return permission_denied. Their reason is PERMISSION_DENIED, and a new credential does not help.

Interactive sessions

Interactive sessions outlive a single credential. The output stream is authenticated only once, when it is established. Each keystroke's SendInput and each Resize and SendSignal is a new RPC that is authenticated again.

Callers like this request a new credential with a new command_id before expires_at and switch to it. They do not need to reopen the output stream. This is what kibo workspace terminal does.

Calling the node

Send requests to session.endpoint with an Authorization: Bearer <credential> header. Only one such header is allowed.

The node data plane uses different TLS settings from ctrl:

  • Trust the system root certificates plus server-ca.pem from the identity, and verify the host name by the standard rules.
  • Do not follow HTTP redirects.
  • Streaming methods need HTTP/2.

For both endpoints side by side, see TLS settings.

Data-plane services

Each method needs the scope listed next to it:

ServiceMethodsRequired scope
FilesystemServiceStat, ListDir, WatchDir (server stream)FILE_READ
FilesystemServiceMakeDir, Move, RemoveFILE_WRITE
ProcessServiceStart (server stream), Attach (server stream), SendInput, CloseStdin, SendSignal, ResizePROCESS
DesktopServiceScreenshot, PerformActionsDESKTOP
ServiceConnectionServiceConnect (bidirectional stream)SERVICE_CONNECT
HTTP /v1/filesGETFILE_READ
HTTP /v1/filesPUTFILE_WRITE
WebSocket /v1/serviceGETSERVICE_CONNECT

For how to use each service, see Commands and terminals, Files, Services and ports, and Desktop.

Stream interruptions

An expired credential affects only new RPCs. Established streams keep running.

The following events end streams in progress:

  • The credential is revoked.
  • The Workspace restarts into a new generation.
  • Someone calls WorkspaceService/RevokeWorkspaceDataPlane.
  • The node switches to a new data-plane process, for example after a node upgrade. HTTP/2 connections to the old process first receive GOAWAY and then close, and streams in progress end with them.

Some client libraries report the close after GOAWAY as a protocol error. For example, the Go Connect client reports invalid_argument: protocol error: incomplete envelope. Treat it as a connection interruption as well: resume process streams and restart directory watches.

Next steps

On this page