On this page

An API key authenticates a person or backend service to MIOSA. User keys are personal credentials. Platform keys are tenant automation credentials and can optionally be restricted to one workspace.

Create a key

From the dashboard: Workspace → Settings → API Keys → New key. Or via API:

POST /api/v1/api-keys

The plaintext msk_* value is returned exactly once at creation. The dashboard shows only a prefix and last four characters thereafter. The server stores only a SHA-256 hash.

If you lose a key, rotate - create a new one, swap it in, delete the old.

Key families


msk_<type>_<random>
  • msk_u_* - user-bound keys for personal CLI and SDK use.
  • msk_p_* - tenant platform keys for server-side automation.
  • msk_a_* - operator-admin keys that are not created through the public self-service API.

Environment-labeled key prefixes are not part of the current self-service contract. Dedicated test-mode billing isolation is planned.

For a server-side platform integration, use a platform key created by a tenant owner or administrator. Never expose it to browser code.

Scopes

Each key has a list of scopes. MIOSA enforces scopes on every mutation. Reads typically require the matching :read scope; writes require :write.

Common scopes:

ScopeAllows
sandboxes:readList, get sandboxes
sandboxes:writeCreate, exec, files.write, destroy
deployments:readList, get deployments, versions, domains
deployments:writeCreate, publish, rollback, attach domains
domains:writeCreate, verify, delete custom domains
databases:writeProvision and operate managed databases
storage:writeProvision and operate object storage
billing:readRead billing and credit information

For server-side platform integration, start with the exact resource scopes the backend needs. User keys created without an explicit scope list receive the standard product scopes. Platform keys are trusted tenant automation credentials, so only tenant owners and administrators can create them.

Rotation

Rotate keys on a schedule (we recommend every 90 days, or on incident). The flow:

  1. Create a new key with the same scopes.
  2. Roll out the new key to your backend (deploy + restart).
  3. Confirm the new key works (recent activity logged with key_id of the new key).

4. Delete the old key

Deleting a key invalidates it immediately. Any in-flight requests using the old key will start getting 401.

Rate limits

Each key has a server-provided request-per-minute limit. The current defaults are 600 rpm for user keys and 30,000 rpm for platform keys, but tenant and endpoint-family limits can be more restrictive.

  • Key ID (the key’s own bucket)
  • Tenant or organization
  • Endpoint (publish has its own bucket, separate from list operations)

Limits scale with the plan. Headers in every response tell you where you stand:


X-RateLimit-Limit: 600
X-RateLimit-Remaining: 547
X-RateLimit-Reset: 1715712060

429 responses include a Retry-After header. SDKs back off automatically.

Audit

Every action authenticated by a key emits an audit event with:

  • api_key_id (so you know which key did what)
  • actor (the organization, plus the key’s name)
  • workspace_id, project_id, external_workspace_id, external_user_id (if passed or resolved in the request)
  • The action (e.g. deployments.publish, domains.create)
  • Timestamp + outcome

Read your audit log via:

GET /api/v1/audit-log?api_key_id=550e8400-e29b-41d4-a716-446655440000
GET /api/v1/audit-log?workspace_id=550e8400-e29b-41d4-a716-446655440000

Browser keys (no)

There is no such thing as a browser-safe msk_*. If you need a browser to call MIOSA-like functionality, mint a scoped browser token server-side. See Browser Tokens.

See also

Was this helpful?