Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.mka1.com/llms.txt

Use this file to discover all available pages before exploring further.

The MKA1 API provides resource-level role-based access control (RBAC) through the authorization endpoints. Use these endpoints to grant, check, and revoke permissions on LLM resources for specific users.

How resource authorization works

Every LLM resource (completion, file, vector store, conversation, response, or skill) can have per-user roles assigned to it. Three roles form a strict hierarchy:
RoleCan do
ownerGrant and revoke roles, plus everything writer can do
writerModify the resource, plus everything reader can do
readerRead the resource
Resource IDs are created when you make LLM API calls. For example, creating a conversation returns a conv_ ID, creating a response returns a resp_ ID, and uploading a file returns a file_ ID. The authenticated caller (or the end user specified via X-On-Behalf-Of) automatically becomes the owner of that resource. Use the returned resource ID with the authorization endpoints below to manage access for other users. Only owners can grant or revoke roles. If a non-owner attempts to grant or revoke, the API returns 403 Forbidden. These authorizations are enforced by the MKA1 backend on every request. Any attempt to read, modify, or delete a resource that the caller does not have access to is rejected with an appropriate error response. You can also grant public access by using "*" as the user ID, but only for writer or reader roles.

Grant a role to a user

Use POST /api/v1/authorization/llm/grant to assign a role to a user on a resource. The caller must be the resource owner.
mka1 permissions llm grant \
  --resource-type conversation \
  --resource-id conv-abc-123 \
  --user-id user_bob \
  --role reader \
  -H 'X-On-Behalf-Of: user_alice'
A successful grant returns 204 No Content. The resourceType must be one of: completion, file, vector_store, conversation, response, or skill. The role must be one of: owner, writer, or reader.

Check a user’s permission

Use GET /api/v1/authorization/llm/check to verify whether the authenticated caller has a specific role on a resource. The response contains an allowed boolean.
mka1 permissions llm check \
  --resource-type conversation \
  --resource-id conv-abc-123 \
  --role reader \
  -H 'X-On-Behalf-Of: user_bob'
{ "allowed": true }
Because roles are hierarchical, an owner also passes a reader or writer check.

Revoke a role

Use POST /api/v1/authorization/llm/revoke to remove a role from a user. Only the resource owner can revoke.
mka1 permissions llm revoke \
  --resource-type conversation \
  --resource-id conv-abc-123 \
  --user-id user_bob \
  --role reader \
  -H 'X-On-Behalf-Of: user_alice'
A successful revoke returns 204 No Content.

Grant public access

Grant a role to all authenticated users by setting userId to "*". Public access is restricted to writer and reader roles — you cannot make someone a public owner.
mka1 permissions llm grant \
  --resource-type conversation \
  --resource-id conv-abc-123 \
  --user-id '*' \
  --role reader

Handle authorization errors

When a non-owner attempts to grant or revoke, the API returns 403 Forbidden:
{
  "error": "Forbidden",
  "message": "Only resource owners can grant or revoke permissions"
}
Always check the caller’s role before attempting permission changes, or handle the 403 response in your application.

End-to-end example: two users with different roles

This walkthrough demonstrates distinct user profiles with differentiated permissions. Alice creates a conversation (becoming its owner), then grants read access to Bob. We verify that Bob can read but cannot write, and that Bob cannot grant permissions to others.
# Step 1 — Alice creates a conversation (she becomes the owner)
CONV_JSON=$(mka1 llm conversations create \
  --body '{ "metadata": { "project": "acme" } }' \
  -H 'X-On-Behalf-Of: user_alice' \
  -o json)
RESOURCE_ID=$(echo "$CONV_JSON" | jq -r '.id')

# Step 2 — Alice grants reader access to Bob
mka1 permissions llm grant \
  --resource-type conversation \
  --resource-id "$RESOURCE_ID" \
  --user-id user_bob \
  --role reader \
  -H 'X-On-Behalf-Of: user_alice'

# Step 3 — Check Bob has reader access (allowed: true)
mka1 permissions llm check \
  --resource-type conversation \
  --resource-id "$RESOURCE_ID" \
  --role reader \
  -H 'X-On-Behalf-Of: user_bob'

# Step 3b — Check Bob does NOT have writer access (allowed: false)
mka1 permissions llm check \
  --resource-type conversation \
  --resource-id "$RESOURCE_ID" \
  --role writer \
  -H 'X-On-Behalf-Of: user_bob'

# Step 4 — Bob tries to grant (returns 403 Forbidden)
mka1 permissions llm grant \
  --resource-type conversation \
  --resource-id "$RESOURCE_ID" \
  --user-id user_charlie \
  --role reader \
  -H 'X-On-Behalf-Of: user_bob'

# Step 5 — Alice revokes Bob's access
mka1 permissions llm revoke \
  --resource-type conversation \
  --resource-id "$RESOURCE_ID" \
  --user-id user_bob \
  --role reader \
  -H 'X-On-Behalf-Of: user_alice'

# Step 6 — Verify Bob is now denied (allowed: false)
mka1 permissions llm check \
  --resource-type conversation \
  --resource-id "$RESOURCE_ID" \
  --role reader \
  -H 'X-On-Behalf-Of: user_bob'

Next steps