---
title: "Mint a mablnet peer JOIN credential for an OAuth-authenticated user"
method: POST
path: "/link/mablnet/authorize/peer"
tags: ["LinkMablnet"]
---

# Mint a mablnet peer JOIN credential for an OAuth-authenticated user

`POST /link/mablnet/authorize/peer`

Issues a single short-lived signed `peer_credential` the calling user presents at JOIN time to be admitted as a peer in a customer tenant. Unlike `/authorize/operator/tenant`, no operator-command token is minted — callers using this endpoint dial the customer's services (e.g., `socks5` for test training) as regular intra-tenant peers; no operator-interface capabilities are involved.
Auth: user-OAuth callers entitled to the tunnel's owner. For a workspace owner, a user with write access to the workspace — customer workspace members training against the workspace's SOCKS5 service, and mabl support admins where the workspace has enabled Support Access. For a company owner, a company admin or any member of the company; there is no standalone mabl global / support admin grant, because no company-level consent flag exists yet to gate one. For a user owner, that user alone.
Lifetime: 30 minutes per issued credential. To keep a longer session alive without changing the bound Host identity, refresh by re-minting with the prior credential's `host_id`.

## Request body

- MablnetPeerCredentialRequest — Request body for `POST /link/mablnet/authorize/peer`. Specifies which customer tunnel the user wants to JOIN as a peer: an owner (`owner_type` + `owner_id`, a workspace or a company) plus the `label`. `workspace_id` is a deprecated alias for `owner_type=workspace` + `owner_id=<workspace_id>`, accepted for older callers — supply either the owner pair or `workspace_id`.
  - `owner_type` 'workspace' | 'company' | 'user' — The kind of entity a mablnet tunnel is scoped to — its "owner". `workspace` is the classic scope: one tunnel per workspace. `company` scopes a single tunnel to an entire company, so every workspace under that company shares one mablnet tenant (and one Link Agent fleet) instead of needing a tunnel each. `user` is a personal tunnel scoped to a single user, private to that user — its egress is the user's own machine, used to route a cloud test run through it. All three are mablnet-only: legacy Link Tunnel is always workspace-scoped.
  - `owner_id` string — The workspace id or company id (per `owner_type`) the user is joining.
  - `workspace_id` string — Deprecated alias for a workspace owner (`owner_type=workspace`, `owner_id=<workspace_id>`). Prefer `owner_type` + `owner_id`.
  - `label` string, required — Tunnel (Link Label) within the owner the user is joining.
  - `host_id` string — Optional. When present the minted credential reuses this `host_id` rather than generating a fresh one, so a long-lived peer session can refresh its credential without changing the Host identity the Router has bound. Shape-only for the peer path — the credential's Ed25519 signature still binds it to the authorized (user, owner, label).

## Response `200`

Peer credential minted successfully.

- MablnetPeerCredentialResponse — Result of a successful `POST /link/mablnet/authorize/peer` call. Carries one signed peer JOIN credential bound to the requested workspace.
  - `peer_credential` string, byte, required — Base64 (standard alphabet, no URL safety) of the UTF-8 JSON bytes of the signed peer JOIN credential. Same shape as the `peer_credential` returned from `/authorize/operator/tenant`.
  - `expires_at` string, date-time, required — RFC 3339 timestamp marking when the credential expires. Fixed 30-minute window from issue time.

## Other responses

- `401` — User not authenticated
- `403` — User not authorized
- `default` — Unknown error

---

[API](https://skmtc.net/mabl/apis/mabl-api.md) · [All operations](https://skmtc.net/mabl/apis/mabl-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/mabl/mabl-api/revisions/d0fc0114da66/schema)
