On this page
← All product updates

Custom Authorization Policies with `@policy` in Hive Router

Dotan Simha
Dotan Simha

Hive Router now supports the Federation @policy directive. @authenticated and @requiresScopes cover authorization the router can decide from a JWT alone, but rules like resource ownership or tenant isolation depend on data the router doesn’t have. @policy delegates exactly that decision to a coprocessor.

Quick Start

Assuming the following simple schema:

extend schema
  @link(url: "https://specs.apollo.dev/federation/v2.6", import: ["@policy"])

type Query {
  users: [User] @policy(policies: [["admin"], ["read_users", "internal"]])
}

policies is an OR of AND groups: users above is allowed if admin is granted, or if both read_users and internal are granted.

Before the graphql.analysis coprocessor stage runs, the router walks the operation and publishes every policy it depends on to the hive::authorization::required_policies request context key, each mapped to null. Your coprocessor decides by overwriting entries with true/false:

graphql.analysis response
{
  "version": 1,
  "control": "continue",
  "context": {
    "hive::authorization::required_policies": {
      "admin": false,
      "read_users": true,
      "internal": true
    }
  }
}

Anything left null, or missing from the answer, is treated as denied — there’s no way to leave a policy undecided and still access the field it protects. Denied fields are then handled exactly like any other unauthorized field, following your configured authorization.directives.unauthorized.mode.

Enable it by wiring the graphql.analysis stage to your coprocessor with context included:

router.config.yaml
coprocessor:
  url: http://127.0.0.1:8081/coprocessor
  protocol: http1
  stages:
    graphql:
      analysis:
        include:
          context: true

Thank you 🙏 to Rafael Guimaraes Siqueira for the initial work on this feature.