# Your signing certificate

Source: https://opvs.ai/docs/guides/vendors/signing-certificate

> The ed25519 key pair that signs every package you publish, how you receive it, and where to keep it.

Every package on `market.opvs.ai` is signed with its vendor's **ed25519** key. OPVS runs a small certificate authority: it creates your key pair, records the public half against your vendor, and gives you the private half **once**.

This is not the credential that authenticates your HTTP calls. That is the [partner key](https://opvs.ai/docs/guides/vendors/partner-keys.md). The certificate signs the package bytes; the partner key authenticates the upload.

## What the signature protects

The public half of your key is checked at three points:

1. **At publish.** The registry checks the signature on your bundle against your registered public key. A mismatch is refused before anything is stored.
2. **At install.** The bundle's SHA-256 and signature are checked before a workspace installs it.
3. **After revocation.** If your certificate is revoked, OPVS disables every install of packages signed with it, normally within about a minute.

There is no way to publish unsigned.

## How you receive it

```
 You ──"please mint my certificate"──▶ OPVS
                                        │ creates the ed25519 key pair
                                        │ keeps the public key + fingerprint
                                        ▼
 You ◀────── email with a one-time link ─┘
  │
  └─ open the link once ──▶ copy the private key into your CI secrets
                            (the link is then used up; OPVS no longer has the key)
```

- **The link works once.** It stops working after the first successful read, or after **72 hours**, whichever comes first.
- **Open it on the machine you will copy from.** Opening it on a phone "to check it works" uses it up.
- **OPVS keeps only the public key and its fingerprint.** If you lose the private key before storing it, ask for a new key pair. There is no "send it again".

## The fingerprint

Each certificate has a SHA-256 fingerprint of its public key, for example:

```
SHA256:00cc2f3aa0f3662dd40fc71a30bf4f5ee927b5845128c8fea29d54e93fbc61f5
```

You will see it in the `cert_fingerprint` field of every package you publish (the CLI fills it in), and on the package detail. Anyone can look up a public key by fingerprint:

```bash
curl -s "https://market.opvs.ai/api/v1/registry/certificates/SHA256:<fingerprint>"
# → { "public_key": "…", "cert_fingerprint": "SHA256:…", "status": "active", "issued_at": "…" }
```

## Where to keep the private key

**In your CI secrets.** GitHub Actions, GitLab CI or any other CI secret store. The publish command reads it from a file or an environment variable and signs locally; the key never leaves the runner. See [Sign and publish](https://opvs.ai/docs/guides/vendors/publish.md).

**Optionally, in a password manager** as a break-glass copy. That is one more place to protect.

**Never** in a repository (even encrypted), a loose laptop file, a chat message or an email. If that has happened, ask OPVS to revoke the certificate and mint a new one.

## More than one certificate

A vendor can hold several active certificates at once. The registry accepts a signature from any of them. That allows:

- **Zero-downtime rotation:** mint the new one, switch CI, then revoke the old one.
- **One per environment** (staging and production) or **one per release engineer**.

## Rotation

There is no enforced expiry. Rotate when you see fit (yearly is a sensible default) and immediately after a suspected leak. The steps are in [Rotate a credential](https://opvs.ai/docs/guides/vendors/rotate-credentials.md).

## Not provided today

- No public revocation-list endpoint. Revocation reaches installs through OPVS's own poller.
- No certificate chains. Each vendor key is checked directly.
- No automatic renewal.

## Next

[Partner keys and publish credentials](https://opvs.ai/docs/guides/vendors/partner-keys.md).
