# Projects and issuers

Understand what a project is, why its URL is the only value a client needs, and how a client finds the project's endpoints and signing keys from it.

A project is one complete identity provider. It has its own people, its own applications, its own signing keys and one URL. Everything in these docs happens inside a project, and every request you make goes to that project's URL.

This page explains the model. To see it working, follow [Add sign-in to an app](/quickstart/sign-in).

## One project, one issuer

Each project has a single URL of this form:

```text
https://<project>.authfi.io
```

That URL is the project's _issuer_: the name the project signs tokens under. It appears as the `iss` claim in every token the project signs. It is also the only value you configure in a client, because everything else can be read from it.

The region a project runs in is never part of the issuer.

These docs use a project called `acme`, whose issuer is `https://acme.authfi.io`.

## Projects are separate

A company usually has more than one project, for example one for production and one for testing. Projects do not share users, keys or tokens. A person in one project does not exist in another, and a token signed by one project does not verify against the keys of another.

## How a client finds the endpoints

A project publishes _discovery documents_: JSON documents at fixed paths under the issuer that list the project's endpoints and what they accept. A client reads its endpoints from these documents and does not hard-code them.

```bash
curl https://acme.authfi.io/.well-known/openid-configuration
```

Each document describes one part of the project.

| Document                                  | What it describes                       | Standard                 |
| ----------------------------------------- | --------------------------------------- | ------------------------ |
| `/.well-known/openid-configuration`       | Sign-in for people and applications     | OpenID Connect Discovery |
| `/.well-known/oauth-authorization-server` | Token endpoint for AI agents            | RFC 8414                 |
| `/.well-known/agent-configuration`        | Agent endpoints and approval methods    | AuthFI                   |
| `/.well-known/oauth-protected-resource`   | The MCP gateway as a protected resource | RFC 9728                 |
| `/.well-known/jwks.json`                  | The project's public signing keys       | RFC 7517                 |
| `/.well-known/ssf-configuration`          | Revocation events you can subscribe to  | OpenID Shared Signals    |

An OpenID Connect library needs only the issuer: it fetches the first document and reads the endpoints from it. The full contents of each document are in [Discovery documents](/reference/discovery).

## How tokens are signed and verified

Each project signs with its own keys. A private key never leaves the project's key service. The public halves are published as a JSON Web Key Set (JWKS, RFC 7517) at `/.well-known/jwks.json`.

| Key     | Algorithm | Signs                                       |
| ------- | --------- | ------------------------------------------- |
| RSA     | `RS256`   | ID tokens issued to people and applications |
| Ed25519 | `EdDSA`   | Access tokens issued to AI agents           |

A service verifies a token in three parts. It fetches the key set and picks the key whose `kid` matches the `kid` in the token's header. It checks the signature with that key. Then it checks that `iss` is the issuer it trusts and that `exp` is in the future. Any JWT library does this when you give it the `jwks_uri`.

<Note title="Keys rotate">
  Cache the key set, and fetch it again when you see a `kid` you do not have. Do not pin a single key.
</Note>

[Keys and secrets](/security/keys) covers rotation and the other keys a project holds.

## Who gets access inside a project

Access in a project is granted to _groups_. Applications, cloud roles, servers and tools are assigned to groups, and a person or agent gets access by being in one. Adding someone to a group gives them everything that group has. Removing them takes it away.

A token carries the caller's groups in the `groups` claim and their roles in the `roles` claim. [Roles, groups and grants](/concepts/access) explains the whole model.

## Next steps

<Cards>
  <Card href="/quickstart/sign-in" title="Add sign-in to an app">
    Use the issuer and the discovery document to sign a person in.
  </Card>
  <Card href="/concepts/access" title="Roles, groups and grants">
    How a project decides what a person or agent may do.
  </Card>
  <Card href="/reference/discovery" title="Discovery documents">
    The contents of every document a project publishes.
  </Card>
  <Card href="/security/keys" title="Keys and secrets">
    Rotate a signing key, and see what your services must do.
  </Card>
</Cards>
