Enterprise deployment

Roll out the skst CLI to your team with a managed policy — soft guardrails that keep the easy path the compliant path, plus a real boundary enforced on our servers.

Two moving parts

  • One generic binary. skst is identical for everyone (npm, Homebrew, or a signed installer). Nothing org-specific is baked into it.
  • Policy is data, delivered separately and refreshed — so it updates without re-installing.

Get the CLI to your people

  • Signed installer (macOS). We can generate a per-org .pkg that installs skst and drops an enrollment.json (your org, a soft enrollment token, and the policy URL). Push it with Jamf/MDM, or hand it out directly.
  • skst enroll <token> — one command enrolls a machine: it writes enrollment.json and fetches your signed policy.
  • Homebrew / npm for the binary itself: brew install skst-dev/tap/skst or npx @skst/skill.

Managed policy (the guardrails)

An admin-owned policy file governs the CLI, modeled on Claude Code's managed-settings.json. It lives at a root-owned path the user can't edit:

OSManaged path
macOS/Library/Application Support/SkillStudio/policy.json
Linux/etc/skill-studio/policy.json
Windows%ProgramData%\SkillStudio\policy.json
  • Author it directly or let the server sign it. The file may be a plain JSON policy you write, or a signed policy from your Skill Studio dashboard — the root-owned location is the trust.
  • Fragments. Drop policy.d/*.json beside it; they merge alphabetically and can only tighten the base (never weaken it) — handy when different teams ship policy pieces.
  • policyHelper. Point policyHelper at an executable; its JSON output becomes the policy at startup — for device-posture or group-aware rules (e.g. call your IdP). Managed-only.
  • Fail-closed. Set failClosed: true to block registry commands when the CLI can't confirm current policy (a stale cache) until it refreshes.

Precedence (highest first): policyHelper → managed file + fragments → cached remote policy → user → built-in default.

What a policy can say

{
  "enforcement": "warn",
  "message": "Acme skills policy",
  "rules": {
    "allowedRegistries": [],
    "blockedCommands": ["unpublish"],
    "requireEnrollment": false,
    "pinnedApiUrl": null
  },
  "refresh": { "ttlSeconds": 3600, "failClosed": false }
}

enforcement is off (silent), warn (a one-line notice), or block (stop with your message). It applies to registry-touching commands (add, publish, unpublish, …).

Delivery via Jamf / MDM

MDM is just transport. Push the root-owned policy.json (and any policy.d fragments) to the managed path with a Jamf policy / configuration profile, GPO, Intune, or your config-management tool. The on-disk contract is identical across macOS, Linux, and Windows.

Soft vs. enforced

Client-side policy is a guardrail — a determined user can work around a CLI on their own machine, and that's expected. The real boundary is server-side: publishing and private-skill access require a per-user token our API validates against your org. Policy keeps the compliant path frictionless; the server is the lock.

Commands

  • skst enroll <token | enrollment.json> — enroll this machine and fetch policy.
  • skst policy show — print the effective policy and which layer it came from.
  • skst policy refresh — force a fresh signed-policy fetch.