Back to all guides
Audit Signing

Audit Signing: Control the Key That Signs Your Audit Records

Configure who manages the signing key for your project's audit records - the platform, or your own key in GCP KMS, AWS KMS, or Azure Key Vault - via the Config API.

What is Audit Signing?

An Audit Signing configuration declares who manages the cryptographic key used to sign your project's audit records, making them tamper-evident. You can choose to have the platform manage the signing key for you; with a customer-managed provider, signing uses a key that lives in your own cloud key store - Google Cloud KMS, AWS KMS, or Azure Key Vault - so key custody, rotation, and revocation stay under your control.

The configuration is a project-scoped Config API object, managed with Service Account credentials like other configurations (Token Introspect, MCP Server, Outbound Events).

Which key providers are supported?

Provider Who holds the key Requires
PLATFORM_MANAGED IndyKite manages the signing key. Only choose this provider. Nothing beyond name and project_id.
CUSTOMER_GCP_KMS Your key in Google Cloud KMS. key_resource + kid, plus provider access material in auth_params.
CUSTOMER_AWS_KMS Your key in AWS KMS. key_resource + kid, plus provider access material in auth_params (e.g. role_arn).
CUSTOMER_AZURE_KEY_VAULT Your key in Azure Key Vault. key_resource + kid, plus provider access material in auth_params.

What fields does the configuration have?

Field Type Description
namestring, requiredURL-friendly identifier, unique within the project. Immutable - it cannot be changed later.
project_idstring (GID), requiredProject that owns the configuration.
display_namestring, optional (2-254 chars)Human-readable name; equals name when not set.
descriptionstring, optional (2-65000 chars)Free-text description.
providerenumPLATFORM_MANAGED (if you want an IndyKite managed provider), CUSTOMER_GCP_KMS, CUSTOMER_AWS_KMS, or CUSTOMER_AZURE_KEY_VAULT. Required on update.
key_resourcestring (max 256)Identifies the key in the provider's namespace (for AWS KMS, the key ARN). Required for every customer-managed provider.
kidstring (max 256)The key ID stamped on signatures so verifiers can select the right key. Required for every customer-managed provider.
auth_paramsmap of string to string (max 32 pairs)Provider access material (for AWS KMS, e.g. role_arn). Write-only: values are accepted on create/update but come back masked as empty strings on every read.

How do I create an Audit Signing configuration?

All endpoints authenticate with a Service Account Bearer token, like the rest of the Config API.

Platform-managed (minimal)

curl -X POST <API_URL>/configs/v1/audit-signings
-H "Content-Type: application/json"
-H "Authorization: Bearer $SERVICE_ACCOUNT_TOKEN"
-d '{
      "name": "audit-signing-default",
      "project_id": "gid-of-project",
      "provider": "PLATFORM_MANAGED"
    }'

Customer-managed key (AWS KMS example)

curl -X POST <API_URL>/configs/v1/audit-signings
-H "Content-Type: application/json"
-H "Authorization: Bearer $SERVICE_ACCOUNT_TOKEN"
-d '{
      "name": "audit-signing-byok",
      "display_name": "Audit signing with our AWS KMS key",
      "description": "Signs audit records with the compliance team key",
      "project_id": "gid-of-project",
      "provider": "CUSTOMER_AWS_KMS",
      "key_resource": "arn:aws:kms:us-east-1:123456789012:key/example-key-id",
      "kid": "audit-2026-q3",
      "auth_params": {
        "role_arn": "arn:aws:iam::123456789012:role/indykite-audit-signer"
      }
    }'

Response (201 Created): the new configuration's id (GID), create_time, created_by, update_time, and updated_by, plus an ETag response header for optimistic concurrency on later updates and deletes.

Reference: POST /audit-signings

How do I read and list configurations?

Read by GID, or by name with the location query parameter; an optional version query parameter reads a specific version:

curl <API_URL>/configs/v1/audit-signings/<id-or-name>?location=<gid-of-project>
-H "Authorization: Bearer $SERVICE_ACCOUNT_TOKEN"

The response includes the configuration fields plus organization_id, timestamps, and authorship - and auth_params values come back masked as empty strings; secrets never round-trip. List every configuration in a project with:

curl <API_URL>/configs/v1/audit-signings?project_id=<gid-of-project>
-H "Authorization: Bearer $SERVICE_ACCOUNT_TOKEN"

The list response wraps the same objects in a data array.

How do I update a configuration?

Send a PUT with an If-Match header carrying the ETag from the last read or write - a stale ETag returns 412 Precondition Failed. provider is required on update; for display_name and description, null keeps the current value while an empty string removes it:

curl -X PUT <API_URL>/configs/v1/audit-signings/<id>
-H "Content-Type: application/json"
-H "Authorization: Bearer $SERVICE_ACCOUNT_TOKEN"
-H "If-Match: $ETAG"
-d '{
      "provider": "CUSTOMER_AWS_KMS",
      "key_resource": "arn:aws:kms:us-east-1:123456789012:key/rotated-key-id",
      "kid": "audit-2026-q4",
      "auth_params": {
        "role_arn": "arn:aws:iam::123456789012:role/indykite-audit-signer"
      }
    }'

Rotating to a new key is exactly this: point key_resource at the new key and change the kid so verifiers can tell old signatures from new ones.

How do I delete a configuration?

curl -X DELETE <API_URL>/configs/v1/audit-signings/<id>?etag=$ETAG
-H "Authorization: Bearer $SERVICE_ACCOUNT_TOKEN"

Response: 204 No Content. The etag query parameter is optional but recommended - like If-Match on update, it prevents deleting a configuration someone else just changed.

What errors should I expect?

Status Meaning
422 Unprocessable EntityValidation failed; the body carries a message and an errors array with the exact reasons: provider is required, key_resource is required for customer-managed providers, kid is required for customer-managed providers.
412 Precondition FailedThe If-Match ETag (or etag query parameter on delete) no longer matches - re-read the configuration and retry.
409 ConflictA configuration with the same name already exists in the project.
404 Not FoundNo configuration with that ID or name (including one already deleted).
401 / 403Missing or insufficient Service Account credentials.

Next Steps