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

# Register your plugin

> What to send Entire to register a plugin, and how to make and rotate its key.

Entire registers each plugin for you. Send your Entire contact the values below. You choose all of them except the slug, which Entire confirms, and the issuer and receipt audience, which follow from the slug.

| Field | What to send | Example |
| :- | :- | :- |
| Owning project | The name of the Entire project that owns your plugin. People who manage that project can manage the plugin. | `acme` |
| Slug | Lowercase letters, digits and single hyphens, at most 40 characters. It can't change later. | `acme-ci` |
| Name, description | How your plugin appears to customers in Entire. | Acme CI, "Runs your tests on every push." |
| Logo | A URL to an SVG or PNG of your mark with no wordmark. Use a transparent background and ideally a square shape. A PNG must be at least 256×256. | `https://ci.acme.example/logo.svg` |
| Issuer | The `iss` claim of your plugin JWTs. Always `urn:entire:plugin:{slug}`, so you don't need to send it. | `urn:entire:plugin:acme-ci` |
| Receipt audience | The `aud` claim Entire puts in your install receipts. Always `urn:entire:plugin:{slug}`, so you don't need to send it. | `urn:entire:plugin:acme-ci` |
| Permissions | `contents:read` to read repository contents, `contents:write` to read and push to them, `checks:write` to [report check runs](https://docs.entire.com/guides/api/plugins/go-sdk.md#report-check-runs), `discussions:write` to [comment on trails](https://docs.entire.com/guides/api/plugins/trail-comments.md), `trails:read` or `trails:write` to read or change trails, `deployments:write` to [report deployments](https://docs.entire.com/guides/api/plugins/deployments.md) such as preview sites, `repositories:create` to [create repositories](https://docs.entire.com/guides/api/plugins/act-for-an-installation.md#create-a-repository) in the customer's project. [Trail events](https://docs.entire.com/guides/api/plugins/trail-events.md) also need `contents:read`. Request only what you use. Only the `contents` permissions reach a repository's Git data. The others, `repositories:create` included, grant no repository read or write, so a plugin that pushes to the repositories it creates also needs `contents:write`. | `contents:read` |
| Public keys | Either Ed25519 public keys in PEM form (up to 10, for rotation), or the URL of a JWKS you serve. Never send the private key. | PEM block |
| Install URL | Optional. HTTPS URL where Entire sends customers who start an install from Entire. It should begin your [install flow](https://docs.entire.com/guides/api/plugins/install-flow.md). | `https://ci.acme.example/install` |
| Post-install URLs | HTTPS URLs that receive the customer after consent, up to 10. Entire compares them character for character. | `https://ci.acme.example/callback` |
| Webhook URL | Optional. HTTPS URL for event deliveries. Entire doesn't follow redirects. | `https://ci.acme.example/webhook` |
| OAuth redirect URIs | Optional. HTTPS URLs that receive the user after [OAuth sign-in](https://docs.entire.com/guides/api/plugins/user-oauth-flow.md), up to 10. Entire compares them character for character. | `https://ci.acme.example/oauth/callback` |

To change your permissions later, ask your Entire contact. New installations get the new set right away. Existing installations get it when Entire updates them, and until then a mint that asks for a new permission answers `409 coverage_changed`.

## Make a key

Make a key with OpenSSL, and send the public half:

```bash theme={null}
openssl genpkey -algorithm ed25519 -out plugin-key.pem
openssl pkey -in plugin-key.pem -pubout
```

> [!WARNING]
>
> Keep `plugin-key.pem` in your secret store. Anyone who holds it can act as your plugin on every installation. To rotate, send the new public key, deploy the new private key, then ask Entire to remove the old public key.

PEM keys are simplest. A JWKS URL suits you if you rotate keys often or keep keys in a KMS: your JWTs must then carry a `kid` header that names the key, and the SDK serves the JWKS for you with `App.JWKSHandler`.
