
# Richtlinie für Signaturschlüssel aktualisieren

`PATCH /v1/signing-keys/policy` · Berechtigung `signing-keys:write`

Aktualisiert die Signaturschlüssel-Richtlinie mit einem JSON Merge Patch (`application/merge-patch+json`, RFC 7396). `If-Match` ist erforderlich: fehlt es, `428`; bei veralteter Version `412`. Wurde die Richtlinie nie geschrieben, ist die Version `"0"`. Ein Patch, der nichts ändert, schreibt nichts und behält die Version.

Eine Änderung von `algorithm` erzeugt sofort einen neuen `next`-Schlüssel mit dem neuen Algorithmus; er kann frühestens 7 Tage später aktiv werden, damit Prüfer, die das JWKS zwischenspeichern, ihn zuerst sehen (eine frühere `immediate`-Rotation schlägt mit `409 next_key_too_young` fehl). Bis dahin signiert der aktive Schlüssel weiter. Eine Änderung von `rotation_interval_days` verschiebt `next_rotation_at`. Eine erfolgreiche Änderung schreibt den Verwaltungs-Audit-Eintrag `signing_key.policy_updated`.

## Anfrage

| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| `If-Match` | header | ja | Das zuletzt gelesene `ETag` der Richtlinie (`"0"`, falls nie geschrieben). Fehlt: `428`; veraltet: `412`. |
| `algorithm` | string | nein | `RS256`, `ES256`, `PS256` oder `EdDSA`. Darf nicht `null` sein. |
| `rotation_interval_days` | integer | nein | 30–365. Darf nicht `null` sein. |
| `storage` | string | nein | `wrapped` (der private Schlüssel wird verschlüsselt unter dem Umgebungsschlüssel gespeichert und nur im Signaturdienst verwendet). `transit` (Schlüssel im Schlüsselverwaltungsdienst) ist noch nicht verfügbar und wird mit `422` abgelehnt. Darf nicht `null` sein. |

## Antwort

`200 OK` mit der aktualisierten Richtlinie und dem neuen `ETag`.

```json
{
  "algorithm": "ES256",
  "rotation_interval_days": 90,
  "storage": "wrapped",
  "next_rotation_at": "2026-12-04T09:30:00.123456Z",
  "updated_at": "2026-10-05T09:30:00.123456Z"
}
```

## Fehler

| HTTP | Code | Wann |
|---|---|---|
| 400 | `unknown_field` | Der Patch enthält ein unbekanntes oder schreibgeschütztes Feld oder ist kein JSON-Objekt (`malformed_request`). |
| 412 | `precondition_failed` | `If-Match` stimmt nicht mit der aktuellen Version überein. |
| 415 | `unsupported_media_type` | Der Content-Type ist nicht `application/merge-patch+json`. |
| 422 | `validation_failed` | Ein Wert ist ungültig (`invalid_value`), außerhalb des Bereichs (`out_of_range`), auf `null` gesetzt (`invalid`), oder `storage` ist `transit`. |
| 428 | `precondition_required` | Der `If-Match`-Header fehlt. |
| 401 | `unauthenticated` | Die Anmeldedaten fehlen, sind ungültig oder wurden widerrufen. |
| 403 | `insufficient_permissions` | Die Anmeldedaten haben nicht die erforderliche Berechtigung. |
| 429 | `rate_limited` | Die Rate-Grenze wurde überschritten; Wiederhole nach dem `Retry-After`-Zeitraum. |
| 501 | `not_implemented` | Die Operation ist in dieser Bereitstellung noch nicht verfügbar; eine Wiederholung ändert das Ergebnis nicht. |
| 503 | `service_unavailable` | Eine Abhängigkeit ist vorübergehend nicht verfügbar; Wiederhole nach dem `Retry-After`-Zeitraum. |

## Beispiel

```bash
curl -X PATCH https://api.eu.keenauth.com/v1/signing-keys/policy \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/merge-patch+json" \
  -H 'If-Match: "0"' \
  -d '{"algorithm":"ES256","rotation_interval_days":90}'
```
