Skip to main content

Overview

Every document has an access policy that controls who can interact with it. The policy uses a deny-by-default model with explicit grants.

Policy shape

{
  "access": {
    "default_effect": "deny",
    "grants": [
      {
        "principal": { "type": "owner" },
        "actions": ["admin"]
      },
      {
        "principal": { "type": "public" },
        "actions": ["query", "read_content", "read_meta"]
      }
    ]
  }
}

Principals

TypeMatchesUse case
ownerThe user who uploaded the documentFull control
publicAny caller, no auth requiredPublic-facing documents (HKEX filings, shared reports)
userA specific user IDShared with a teammate
orgAll members of an orgOrg-wide access
projectAll keys scoped to a projectProject-level access

Actions

ActionWhat it permits
adminAll operations (superset)
queryChat completions, structured extraction
read_contentPage markdown, node content
read_metaDocument status, metadata
download_pdfOriginal PDF download
update_configChange settings and access policy
trigger_extractStart extraction jobs
publishPublish to public corpus
create_linkCreate share links
list_linksView existing share links

Setting the policy

curl -X PUT https://api.okrapdf.com/document/{id}/config \
  -H "Authorization: Bearer okra_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "access": {
      "default_effect": "deny",
      "grants": [
        {
          "principal": { "type": "owner" },
          "actions": ["admin"]
        },
        {
          "principal": { "type": "public" },
          "actions": ["query", "read_content", "read_meta"]
        }
      ]
    }
  }'

Response (200)

{
  "document_id": "doc-abc123",
  "config_version": 1,
  "config": {
    "access": {
      "default_effect": "deny",
      "grants": [
        { "principal": { "type": "owner" }, "actions": ["admin"] },
        { "principal": { "type": "public" }, "actions": ["query", "read_content", "read_meta"] }
      ]
    }
  }
}

Grant constraints

Grants can have optional constraints:
{
  "principal": { "type": "user", "id": "user_abc" },
  "actions": ["query"],
  "constraints": {
    "expires_at": "2026-06-01T00:00:00Z",
    "not_before": "2026-03-01T00:00:00Z"
  }
}
ConstraintEffect
expires_atGrant stops working after this time
not_beforeGrant only active after this time
redaction_roleApplies PII redaction profile (admin, viewer, public)

Common patterns

Public document (anyone can chat)

{
  "grants": [
    { "principal": { "type": "owner" }, "actions": ["admin"] },
    { "principal": { "type": "public" }, "actions": ["query", "read_content", "read_meta"] }
  ]
}

Org-internal document

{
  "grants": [
    { "principal": { "type": "owner" }, "actions": ["admin"] },
    { "principal": { "type": "org", "id": "org_xyz" }, "actions": ["query", "read_content"] }
  ]
}

Time-limited share

{
  "grants": [
    { "principal": { "type": "owner" }, "actions": ["admin"] },
    {
      "principal": { "type": "user", "id": "user_abc" },
      "actions": ["query", "read_content"],
      "constraints": { "expires_at": "2026-04-01T00:00:00Z" }
    }
  ]
}