# Enforce field-level permissions from the schema itself

Declare access requirements with `@authenticated` and `@requiresScopes`. The router evaluates them before any resolver runs. Directives propagate from subgraph schemas to the federated graph automatically.

Requires Router 0.60.0+. Works with JWT Authentication.

## The problem

## Authorization scattered across resolvers is a liability

In a federated graph, each team implements access control independently. The result is inconsistent enforcement and no visible record of what each field requires.

### Authorization logic lives in resolver code

Each resolver that handles sensitive data contains its own access checks. There is no single place to see what each field requires. Auditing means reading every resolver.

### Enforcement is inconsistent across subgraphs

In a federated graph, each subgraph team implements authorization independently. One subgraph enforces scope checks; another does not. The gaps are invisible until something is accessed that should not be.

### Access requirements are not visible in the schema

Developers reading the schema cannot tell which fields require authentication or which scopes are needed. That context exists only in the implementation — not in the API contract.

## Our solution

## The schema documents and enforces access requirements

Authorization directives embed access requirements directly in the GraphQL schema. The router evaluates them before execution — no code changes needed in resolvers.

### From schema declaration to enforcement

1. Declare `@authenticated` on any field, object, interface, enum, or scalar that requires authentication.
2. Declare `@requiresScopes` with a nested array of scope requirements. Inner arrays are AND conditions; outer arrays are OR conditions.
3. Directives declared in a subgraph schema propagate automatically to the federated schema during composition.
4. At request time, the router evaluates directives before query execution — no resolver code runs for unauthorized fields.
5. Nullable fields return partial data with authorization errors. If a non-nullable field fails authorization, the entire response data returns null.
6. `@requiresScopes` error messages specify the required and actual scopes, giving clients actionable context. `@authenticated` errors state the reason: not authenticated.

JWT Authentication must be configured. Router 0.60.0+, Control Plane 0.58.0+.

## Authorization directives

## Before & After

| Before Cosmo                                         | With Cosmo                                             |
|-----------------------------------------------------|-------------------------------------------------------|
| Authorization checks scattered across resolver functions | Declarative directives in the schema                   |
| No single source of truth for access requirements       | Schema documents and enforces requirements simultaneously |
| Each subgraph implements authorization independently     | Directives propagate automatically to the federated graph |
| Custom code for every protected field                    | `@authenticated` or `@requiresScopes` in one line      |

## Scope logic

### AND / OR with nested arrays

`@requiresScopes(scopes: [[
