Guest Machines

Authentication

Choose between service principals, delegated tokens, and human sessions.

Every authenticated API request resolves to a principal. Authorization then evaluates the principal type, organization boundary, scopes, resource visibility, ownership, and role.

Service principals

Use a service principal for server-to-server automation owned by an organization. Its API key uses the gsmc_sk_ prefix and is sent as a Bearer token.

Service principals have no human membership. Their access comes from scopes and, when configured, a resource allowlist. They cannot administer other service principals.

Private resources are invisible to service principals

Scopes are not sufficient on their own. A service principal can never read or invoke a resource whose visibility is private, no matter which scopes it holds — the visibility check runs first and denies outright.

Agents, pipelines, and chats are created private by default, so a new automation account typically sees nothing until you act:

  • share the resource with the organization, which makes it visible to every member and to organization-owned automation; or
  • set the resource to restricted visibility and grant the service principal explicit access — for restricted resources, scope plus grant are both required.

Plan for this before granting scopes. A correctly scoped key against private resources produces an empty list, not an error.

Delegated clients and tokens

Use delegated access when an external application acts on behalf of a specific user. Delegated tokens use the gsmc_dt_ prefix, carry the user's identity for attribution and ownership, and remain restricted by granted scopes.

Each delegated token is locked to the organization that issued it. It does not switch organizations with X-Org-Id; issue and consent to a token in each organization the integration needs to reach.

A delegate is not a stand-in for the user's full account. It normally reaches resources through the user's ownership and its own scope grant rather than inheriting administrative powers. Organization-library MCP management is a narrow exception: it requires the exact mcp_servers:publish scope and the represented user must currently be an organization admin or owner.

Delegated access is appropriate when attribution and the user's own resources matter. It is not a substitute for an organization-owned background integration, and it cannot script admin operations outside the documented MCP library exception.

Provision user-owned configurations

Use a delegated token when an external application needs to create agents, teams, pipelines, or MCP connectors for a user. Creation requires the matching agents:create, teams:create, pipelines:create, or mcp_servers:create scope and binds the new resource to the delegated user; a service principal cannot create these resources because it has no user identity to own them.

With the corresponding :edit scope, a delegate can update only resources owned by its user. It does not inherit an administrator's ability to edit someone else's configuration. Pipeline writes also require invoke access to every referenced agent, team, and fallback target. Creating a team with members—or adding members later—likewise requires agents:invoke for each newly introduced agent, and a delegate cannot add another user's private agent.

For organization-library MCP connectors, grant mcp_servers:publish explicitly. Publishing, unpublishing, creating an organization-shared connector, or testing one with its saved credential also checks the represented user's current admin or owner role. The mcp_servers:* wildcard does not grant this permission.

Installing a delegated integration starts with a signed-in user:

  1. An organization admin registers the client with POST /api/v1/oauth-clients and stores the client secret returned once.
  2. A member lists installable clients with GET /api/v1/oauth-clients/available, reviews the requested scopes, and grants the client access with POST /api/v1/oauth-clients/{client_id}/grant.
  3. The member can withdraw that consent with DELETE /api/v1/oauth-clients/{client_id}/grant, which also revokes their active tokens for the client.

These are onboarding and consent actions, so they use the member's short-lived user session. Never capture or store that session as an integration credential. After consent, the integration uses its client credentials only for token exchange, then sends the resulting delegated token to API operations.

Exchange client credentials for a token

After a user grants your client access, exchange the client credentials server-to-server:

curl https://api.guestmachines.com/api/v1/auth/token/exchange \
  -H 'Content-Type: application/json' \
  -d '{
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "user_id": "USER_UUID",
    "scopes": ["agents:read", "agents:invoke"],
    "expires_in_seconds": 3600
  }'

Do not send an existing Bearer token to this endpoint. The requested scopes must fit both the client's allowance and the user's active grant. The response returns a gsmc_dt_ token once in raw_token; store it securely and exchange again when it expires.

Drive human-in-the-loop runs

Use a delegated token for work that can call ask_user or pause for tool approval. The token gives the run an attributed actor and can later retrieve the pending interaction with runs:read and answer it with runs:edit.

That decision boundary is stricter than ordinary run administration. Only the user who started the run can read or answer the interaction. A delegate cannot answer another user's run, an organization admin cannot use their role as an override, and a service principal has no user identity to submit a decision. See human interactions for the complete flow.

Own uploaded run inputs

Artifact upload preserves the caller's identity boundary. A direct user-session or delegated-token upload is private and owned by that user. A service-principal upload is organization-shared because a service principal has no user identity; do not use one when the file must remain private to a person. The API never converts either kind of upload into a run-produced output.

The minimum upload scope for a machine credential is runs:create. To attach the returned artifact through artifact_inputs, also grant runs:read and the scope that invokes the target, such as agents:invoke, teams:invoke, or pipelines:invoke. Listing the workspace's ready artifacts needs runs:list. Downloading or previewing one needs runs:read; deleting one needs runs:edit and still follows its ownership and visibility rules. Direct viewers cannot upload.

Resource allowlists change this flow for service principals. A principal with an allowlist cannot create an upload. For existing artifacts, that principal can list, read, download, preview, delete, or attach only a caller-uploaded artifact whose exact UUID appears in the allowlist. Run-produced artifacts are omitted entirely for an allowlisted service principal, including when a related agent or run is allowlisted. Use an unrestricted service principal to create organization-owned uploads, then add only the resulting upload UUIDs to the restricted principal that consumes them.

Human sessions

Browser session credentials are short-lived. The public Authentication API accepts them only for the documented human onboarding and consent operations. Do not copy them into an integration.

Key handling

  • Store keys in a secret manager.
  • Use separate principals for separate systems.
  • Grant the narrowest useful scopes.
  • Rotate keys without reusing names or values.
  • Revoke a key immediately if it may have leaked.
  • Never expose service-principal keys to client-side JavaScript.

On this page