### TL;DR

The `@inaccessible` directive hides fields from the public client schema while keeping them available in the Supergraph for the Router to use. Applied to `@key` fields, this unlocks two patterns: Internal Keys — join subgraphs using different internal identifiers without exposing them to clients, useful for heterogeneous databases and legacy migrations — and Zero Trust Data Access — pass short-lived access tokens between services as inaccessible keys, so sensitive data requires explicit authorization even from internal services.

Using `@inaccessible` keys in your Subgraphs is a very powerful addition to your federated GraphQL Schema design toolbox. In this post, we'll be looking at two very powerful patterns that you can implement using `@inaccessible` keys.

| Pattern | Problem it solves |
| --- | --- |
| Internal Keys | Different internal IDs across subgraphs/databases |
| Legacy Migration | Supporting old and new identifiers during migration |
| Zero Trust Access | Enforcing strong auth for sensitive data across services |

1. **Internal Keys** - How to hide data access keys from the public
2. **Zero Trust Data Access** - How to manage access to sensitive data in a federated GraphQL API

### The basics of the `@key` directive in GraphQL Federation

#### What does the `@key` directive do in GraphQL Federation?

The `@key` directive defines a unique identifier for a type in your federated GraphQL schema. This identifier can be used by the Router to "join" data from different subgraphs together.

Here's a simple example of how we could use the `@key` directive to join `Posts` from a `Blog` subgraph with `Authors` from a `User` subgraph:

```graphql
# Blog subgraph
type Post @key(fields: "id") {
  id: ID!
  title: String!
  author: User!
}

type User @key(fields: "id") {
  id: ID!
  posts: [Post!]!
}
```

```graphql
# User subgraph
type User @key(fields: "id") {
  id: ID!
  name: String!
}

type Query {
  user(id: ID!): User
}
```

### How does the `@inaccessible` directive work in federated GraphQL APIs?

To understand the `@inaccessible` directive we have to first understand how GraphQL Federation Routers work, and how they expose data from different subgraphs to the public.

The Router serves one schema which is publicly accessible (client schema) and another which is a superset (Supergraph schema). The Supergraph schema can contain `@inaccessible` fields that are not part of the public schema, but are still usable internally for the Router's operations.

### Using the `@inaccessible` directive for Internal Keys in Federated GraphQL APIs

#### When should I use internal `@inaccessible` keys instead of public IDs?

This is important in API design as it helps to hide implementation details from the public. For instance, if the `User` subgraph uses a serial primary key in a PostgreSQL database, while a `Post` subgraph uses UUIDs, we can leverage the `@inaccessible` directive to add an internal key in the `User` type.

### Using `@inaccessible` keys to migrate legacy systems in Federated GraphQL APIs

You can support both legacy and new identifiers during a migration. For example, if we want to migrate the `User` subgraph from MySQL to PostgreSQL, we can add an `@inaccessible` key for the new UUID identifier while retaining the old serial key until the migration is complete.

### Using the `@inaccessible` directive for Zero Trust Data Access in Federated GraphQL APIs

In a Zero Trust architecture, we enforce that sensitive data is only accessible if the client has valid credentials. For example, a `Patient` service could expose a `shortLivedAccessToken` as an `@inaccessible` field, which cannot be accessed publicly but can be used internally to control access to other sensitive data.

### Conclusion

In this exploration, we've discussed how the `@inaccessible` directive transforms schema design in federated GraphQL APIs. The patterns we examined, including Internal Keys and Zero Trust Data Access, provide powerful techniques for managing identifiers across different subgraphs and securing access to sensitive data.
