> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nightshift.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Policies

> How access works in Nightshift — for people, tokens, and the agents acting through them

Nightshift is built for agents to do real work in — which only makes sense if every
action is governed. The policy system is that governance: **every single statement**,
whether it comes from you in the console, Claude over MCP, or a published app, is
authorized against the same model before it touches your data.

The good news: you rarely have to think about it. Defaults are sensible, agents see and
respect the same boundaries you do, and there's exactly one model to understand.

## The model

Access in Nightshift is a set of grants. A grant answers three questions:

> **Who** (an org member, or an API token) can do **what** (read, update, delete) to
> **which object** (a table, view, notebook, or app)?

A grant can also apply to *all* objects of a kind instead of one — that's what we call a
**capability**. The capabilities you'll encounter:

| Capability                               | What it allows                                               |
| ---------------------------------------- | ------------------------------------------------------------ |
| Create tables & views (`objects:create`) | `CREATE TABLE` / `CREATE VIEW` in the warehouse              |
| Create apps (`app:create`)               | Creating and first-publishing apps                           |
| Restore snapshots                        | Rolling the warehouse back to a previous [snapshot](/audits) |

That's the whole vocabulary. There's no separate permission system for the console, the
MCP server, and apps — they all resolve to these grants.

## The defaults

* **Deny by default.** A member (or token) with no grant on a table can't read it — and
  can't confirm it exists.
* **You own what you create.** Creating a table, view, notebook, or app automatically
  grants you update and delete on it.
* **Write implies read.** Update or delete access to an object includes read access.
  Create doesn't imply anything about existing objects.
* **Owners and admins skip grant checks.** They can act on anything in the org (the
  platform-wide guardrails below still apply to them).

There is also one **delegation rule**, and it's the same everywhere: *you can only grant
access you already hold.* Sharing an app, granting a teammate read on a table, minting a
token — all of it is bounded by your own access. Admins can grant anything.

## Roles

Org members have one of three roles:

* **Owner / Admin** — bypass grant checks, manage invites, tokens, and the audit log.
* **Member** — governed by grants. Members can still share and delegate freely — just
  never beyond what they hold themselves.

## Tokens

An API token (`nsk_…`) is a scoped identity you mint from the **Tokens** page in the
[console](https://console.nightshift.sh). Tokens are how anything non-human authenticates:
a headless agent, a CI job, a Fiber app's dev environment.

What makes them safe to hand out:

* **A token holds an explicit list of grants**, chosen when you mint it — and it can only
  carry access *you* hold (the delegation rule again). It's an attenuated copy of you,
  never an amplified one.
* **Never admin, pinned to one org.** Even an admin's token is a plain grant-scoped
  identity.
* **The secret is shown once**, at creation. Nightshift stores only a hash and a display
  prefix.
* **Expiry and revocation** are built in, and every token shows its last-used time — so
  stale credentials are easy to spot and kill.

<Note>
  When you connect Claude to Nightshift through the standard OAuth flow, it acts **as you**
  — your grants, your role. That's usually what you want: it's convenient, and everything
  it does is attributed and [audited](/audits). Mint a scoped token instead when something
  runs unattended, or when you deliberately want a narrower blast radius.
</Note>

## What a denial looks like

When an action isn't allowed, the answer is a plain, specific error — for example:

```
missing permission: table:update on sales
```

Agents read these too. In practice Claude will hit a denial, understand exactly what's
missing, and either work within its access or tell you what grant it needs — no silent
failures, no guessing.

## Platform guardrails

A few rules apply to *everyone*, including owners and admins:

* **No side doors into or out of the warehouse.** Statements like `COPY`, `ATTACH`,
  `INSTALL`, and direct file reads (`read_csv`, `read_parquet`, `s3://…` paths) are
  blocked in queries. External data comes in through **Add Data**, where credentials are
  managed properly — never pasted into SQL.
* **No secrets in SQL.** `CREATE SECRET` is blocked for the same reason.
* **One statement per request.** Every statement is authorized individually; there's no
  smuggling a write inside a batch.

## How apps fit in

Published apps are the policy system's showcase: at publish time, every query in the app
is vetted under the *publisher's* grants and frozen into the app's [manifest](/apps). At
runtime the app runs under its own identity and can execute **only** those manifest
entries. Viewers get the app's output without holding — or needing — any grant on the
underlying tables. See [Apps](/apps) and [Sharing](/sharing).
