Consuming approved skills¶
The facade is an ordinary read-only git remote, so clients need no modification — only a credential and a URL.
The wizard does steps 1–4 for you
On a marketplace's detail page in the portal, Set up a client composes
the exact commands below for that marketplace — token creation (show-once,
as always), the credential line, the claude plugin marketplace add
command, and the clone URL — each with a copy button. The rest of this
guide is the same procedure by hand. See
the portal reference.
1. Get a credential¶
Git clients authenticate with a token, not with your portal session cookie. There are two kinds, and for a human at a keyboard the first is the better default.
A session credential (recommended for people)¶
If you are already logged in to the portal, mint a credential from that session instead of creating a standing token:
$ curl -X POST localhost:8080/api/tokens/session \
-H 'Content-Type: application/json' -d '{"name":"my-laptop"}'
{"id":1,"name":"my-laptop","token":"sgw_...","expiresAt":"2026-08-23T17:00:00Z",
"sessionDerived":true,"pushScopes":[]}
The gateway sets the lifetime —
skills-gateway.tokens.session-ttl,
8 hours by default — and you cannot ask for longer. That is the entire
difference between this and a personal access token: a credential whose life
the holder chooses is a standing credential wearing a different name. It also
carries no publication authority, and it is marked sessionDerived wherever it
appears, so the audit ledger distinguishes
"a fetch by a credential minted moments after an SSO login" from "a fetch by a
token provisioned months ago".
The timer is the control, not your session
A session credential is not revoked when you log out or close the browser — the gateway does not track session lifetime. It dies when its expiry passes, and until then it is a bearer token like any other. What it buys is a bounded window and an attributable origin, not immunity.
A personal access token (for CI, and anything without a browser)¶
Git clients authenticate with PATs, not with your portal session.
Shown exactly once
Only a SHA-256 digest is stored. A lost token cannot be recovered — revoke it and create another.
Tokens are scoped to the creating principal: you only ever see and revoke your own.
Scope it, expire it, rotate it
A token can be limited to named marketplaces ("scopes":["acme","catalog"])
and given an expiry ("expiresAt":"...") — a leaked CI token limited to one
marketplace is an incident contained to that marketplace, and one that dies
on its own bounds the window a leak matters. Suspect exposure without
wanting to reconfigure anything? POST /api/tokens/{id}/rotate issues a
fresh secret with the identical grant and kills the old one in the same
act. See Access tokens.
2. Verify the remote¶
The username is ignored; the token goes in the password field.
A 404 here means the marketplace has never had a snapshot approved — there is nothing to serve. A 401 means the token is wrong or revoked.
3. Store the credential¶
So the client never prompts:
$ printf 'protocol=https\nhost=skills.corp.example\nusername=token\npassword=sgw_...\n' \
| git credential approve
Or configure the username and let your credential helper hold the secret:
4. Point your agent at it¶
One URL for everything
Instead of adding each marketplace separately, add the
virtual catalog — /git/catalog — which aggregates
the currently approved snapshot of every governed marketplace, with plugin
names prefixed by their marketplace.
Point the tool at the same URL as an ordinary skills repository — the facade serves plain git, and the open Agent Skills format needs nothing more.
What clients see¶
Exactly one branch, main, at the approved SHA. Unapproved snapshots do not
exist on this remote, and pushing here is impossible — receive-pack is disabled
by construction on the facade, so git push gets a "service not enabled"
rejection. (Publishing to a marketplace the gateway hosts is a different
endpoint and a different credential; see
Publishing first-party skills.)
The served SHA changes only when a reviewer approves a new snapshot. Upstream movement alone never changes what you receive.
Every fetch is recorded¶
Each git fetch appends entries to the audit ledger with your principal, the
marketplace, the ref and the SHA. Check the portal's Audit log page.
This is what makes "which identities ever received this exact content" answerable — see Snapshots and the audit ledger.
Making the gateway the only door¶
Governance that relies on developers choosing the right URL is documentation, not control. Two mechanisms carry the load:
Fleet-managed client settings. Claude Code's managed settings support
strictKnownMarketplaces (managed-only), which restricts users to an explicit
marketplace allowlist. Combined with extraKnownMarketplaces and
enabledPlugins you can pre-register the gateway and force-install the approved
set. Distribute via MDM. Copilot and Cursor have no equivalent hard switch
today.
Network egress policy. Block — or at minimum alert on — direct access from developer machines and CI to upstream marketplace hosts. Blocked attempts are themselves a useful signal.
And the carrot. The gateway is faster (LAN-local), simpler (one URL, a pre-approved catalog, no security tickets) and works in restricted networks. Making the paved road genuinely better is half of enforcement.