Scopes & Auth

Scopes, permissions, and tokens are Cinch's core access primitives. Together they answer three questions: where can you access,what can you do, and who are you.

The mental model

Scopes are the "where." A scope is a boundary that contains databases and child scopes. If you are not inside a scope, you cannot see anything in it.

Permissions are the "what." Three levels: read, write, admin. They control whether you can query data, modify data, or manage infrastructure (create databases, issue tokens).

Tokens are the "who." A token encodes both a scope (where) and a permission (what). Hand someone a token and they get exactly that access, nothing more.

Scopes: where you can access

Every database belongs to exactly one scope. Scopes nest up to 10 levels deep, forming a tree. A token for a parent scope grants access to everything in its descendants. A token for a child scope cannot see anything in its parent or siblings.

# Scope hierarchy
acme (org) / api (project) / production (environment)

├── scope: web-app
     ├── db: sessions (redis)
     └── db: cache (redis)

├── scope: agents
     ├── db: shared-memory (redis)

     ├── scope: agent-task-001
     ├── db: scratch (redis)
     └── db: findings (sql)

     └── scope: agent-task-002
           └── db: scratch (redis)

└── scope: analytics
      └── db: events (sql)

In this example, a token for the agents scope can see shared-memory,agent-task-001/*, andagent-task-002/*. But it cannot see web-app oranalytics. A token for agent-task-001 can only see its own two databases.

Permissions: what you can do

Every scope token has one of three permission levels:

LevelData accessManagement
readRead data from databasesList databases and scopes
writeRead and write dataList databases and scopes
adminRead and write dataCreate/delete databases and child scopes. Issue tokens.

The most important rule: permissions only go down, never up. An admin can issue write tokens. A write token can issue read tokens. But a write token cannot issue admin tokens, and a read token cannot issue any tokens at all. Delegation never escalates privilege.

Tokens: who you are

Three token types serve different roles:

TokenFormatWho holds itWhat it does
API keyck_live_...Your backend, dashboard, CIFull account access. Creates scopes, databases, and tokens.
Scope tokencinch_...Agents, services, tenantsAccess to one scope. Manages databases within that scope.
Database tokencinch_...Redis/Bolt/HTTP connectionsAccess to one database. Auto-issued when you call db.url().

API keys and scope tokens are for managing databases (creating, listing, deleting) through the SDK or REST API. Database tokens are for using databases (reading and writing data) through Redis, Bolt, or HTTP clients. The SDK handles the exchange between them automatically: call db.url() and you get a database URL plus an auth token.

Putting it together

Here is all three primitives working together. A backend orchestrator creates a scope for an agent, provisions a database, issues a scoped token, and hands it off. The agent uses the token to access its databases. When the task is done, deleting the scope cleans up everything.

Orchestrator

from cinchdb import Cinch

# Backend holds an API key (full access)
client = Cinch(api_key="ck_live_...", org="acme")

# Create a scope for this agent task
scope = client.scope("agent-task-001", environment="production", project="api")

# Create a database inside the scope
db = scope.create_database(type="redis", name="scratch")

# Issue a write token scoped to this task
token_resp = scope.token(permission="write", expires_in_days=1)

# Hand the token to the agent
# The agent can read/write databases in this scope,
# but cannot create databases, access sibling scopes,
# or see anything outside this scope.
send_to_agent(token_resp["token"])

Agent

import os
import redis
from cinchdb import Cinch

# Agent receives its scope token
agent = Cinch(scope_token=os.environ["CINCH_SCOPE_TOKEN"])

# See what databases are available
dbs = agent.scope_auth_databases()

# Connect to a database
db = agent.scope_auth_database("database-id")
r = redis.from_url(str(db.url()))

# Do work
r.hset("findings", "key-insight", "the answer is 42")
r.lpush("log", "analysis complete")

Cleanup

# When the task is done, delete the scope
scope.delete()
# Everything inside is removed: databases, child scopes, tokens.
# Archived data in cold storage is cleaned up too.

Credential safety

Connection URLs returned by the SDK are wrapped in a RedactedUrl object. When you pass it to a client library (like redis.from_url), it returns the full URL with the token. When you print or log it, the token is replaced with ***, so credentials never leak into logs or error reports.

Token expiry

Set expires_in_days when issuing scope tokens. Short-lived tokens limit the blast radius if a credential is compromised. For long-running services, use the SDK's automatic retry and refresh.

See the Python SDK or TypeScript SDK docs for the full API.