Audit Signing: Manage Signing Key Configurations via REST
This example demonstrates the Audit Signing configuration REST endpoints (/configs/v1/audit-signings).
What is an Audit Signing configuration?
It declares who manages the cryptographic key used to sign your project's audit records, making them tamper-evident:
- PLATFORM_MANAGED (default): IndyKite manages the signing key
- CUSTOMER_GCP_KMS / CUSTOMER_AWS_KMS / CUSTOMER_AZURE_KEY_VAULT: signing uses your own key
in your cloud key store - identified by key_resource (e.g. the AWS KMS key ARN, max 256 chars)
and kid (the key ID stamped on signatures, max 256 chars), with provider access material
in auth_params (max 32 string pairs)
Key behaviors shown:
1. Create with defaults - name, project_id and provider.
2. Create with a customer-managed key - key_resource and kid become required
3. Read - by GID or by name + project_id/location; auth_params values come back masked as empty strings
4. Update with If-Match ETag - rotate to a new key by changing key_resource and kid
5. Delete with the etag query parameter - 204 No Content
Validation errors are explicit: a 422 response lists the exact reason, e.g.
"key_resource is required for customer-managed providers".
Use case
Scenario: A compliance team must prove that audit records have not been altered, using a signing key the company controls.
Flow:
1. The team creates an AWS KMS key and an IAM role that permits signing with it
2. Ops creates an Audit Signing configuration: provider CUSTOMER_AWS_KMS,
key_resource = the key's ARN, kid = "audit-2026-q3", auth_params.role_arn = the role
3. The project's audit records are now signed with the customer-held key;
verifiers use the kid to select the right public key
4. At the quarterly rotation, ops PUTs the configuration with the new key ARN and
kid "audit-2026-q4", guarded by If-Match so concurrent edits fail loudly (412)
5. Reading the configuration never leaks secrets: auth_params values are masked
Key custody stays with the company: revoking the key or the role in AWS
immediately withdraws the platform's ability to sign with it.
Requirements
Prerequisites:
- ServiceAccount credentials: All /configs/v1/audit-signings endpoints authenticate with a Service Account Bearer token
- Project GID: The project (application space) the configuration belongs to
- For customer-managed providers: a signing key in GCP KMS, AWS KMS, or Azure Key Vault, plus the access material the platform should use (e.g. an AWS IAM role ARN)
Field constraints:
- name: URL-friendly, unique in the project, immutable
- display_name: 2-254 chars (optional)
- description: 2-65000 chars (optional)
- provider: PLATFORM_MANAGED | CUSTOMER_GCP_KMS | CUSTOMER_AWS_KMS | CUSTOMER_AZURE_KEY_VAULT
- key_resource, kid: max 256 chars; required for every customer-managed provider
- auth_params: up to 32 string pairs; write-only (masked on read)
Steps
Step 1: Create a platform-managed configuration
- POST /configs/v1/audit-signings with name, project_id, provider PLATFORM_MANAGED
- Result: 201 with id, timestamps, authorship - and an ETag response header
Step 2: Create a customer-managed configuration (AWS KMS)
- POST with provider CUSTOMER_AWS_KMS, key_resource (key ARN), kid, auth_params.role_arn
- Omitting key_resource or kid returns 422 with the exact validation error
Step 3: Read the configuration
- GET /configs/v1/audit-signings/{id}, or /{name}location=<gid>; optional version query parameter
- auth_params values are masked as empty strings; response carries a fresh ETag
Step 4: List the project's configurations
- GET /configs/v1/audit-signings?project_id=<gid> returns { "data": [...] }
Step 5: Update to rotate the key
- PUT /configs/v1/audit-signings/{id} with If-Match: <etag>; provider is required on update
- New key_resource + new kid = key rotation; a stale ETag returns 412 Precondition Failed
- For display_name/description: null keeps the value, empty string removes it
Step 6: Delete
- DELETE /configs/v1/audit-signings/{id}?etag=<etag> returns 204 No Content
Step 1
Create a platform-managed Audit Signing configuration - the minimal form. Choose PLATFORM_MANAGED provider.
{
"name": "audit-signing-default",
"project_id": "gid-of-project",
"provider": "PLATFORM_MANAGED"
}Step 2
Create a configuration backed by your own AWS KMS key. key_resource identifies the key (its ARN), kid is the key ID stamped on signatures, and auth_params carries the access material (here an IAM role ARN). For GCP KMS or Azure Key Vault, use that provider's key identifier in key_resource.
{
"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"
}
}Create response (201): the configuration GID, timestamps, and authorship. Save the ETag response header for Step 5 and Step 6.
{
"id": "gid:example-audit-signing-config-id",
"create_time": "2026-09-03T09:00:00Z",
"created_by": "gid:example-service-account-id",
"update_time": "2026-09-03T09:00:00Z",
"updated_by": "gid:example-service-account-id"
}Step 3
Read the configuration by GID, or by name with the project_id query parameter.
curl <API_URL>/configs/v1/audit-signings/<id-or-name>?project_id=<gid-of-project> \
-H "Authorization: Bearer $SERVICE_ACCOUNT_TOKEN"Read response: all fields plus organization_id - with auth_params values masked as empty strings. Secrets never round-trip.
{
"id": "gid:example-audit-signing-config-id",
"name": "audit-signing-byok",
"display_name": "Audit signing with our AWS KMS key",
"description": "Signs audit records with the compliance team key",
"create_time": "2026-09-03T09:00:00Z",
"created_by": "gid:example-service-account-id",
"update_time": "2026-09-03T09:00:00Z",
"updated_by": "gid:example-service-account-id",
"organization_id": "gid:example-organization-id",
"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": ""
}
}Step 4
List every Audit Signing configuration in the project.
curl <API_URL>/configs/v1/audit-signings?project_id=<gid-of-project> \
-H "Authorization: Bearer $SERVICE_ACCOUNT_TOKEN"
# Response: { "data": [ <one read response object per configuration> ] }Step 5
Rotate the key: PUT with If-Match carrying the last ETag, pointing key_resource at the new key and bumping kid so verifiers can tell old signatures from new. provider is required on update.
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"
}
}'Step 6
Delete the configuration, guarded by the etag query parameter.
curl -X DELETE "<API_URL>/configs/v1/audit-signings/<id>?etag=$ETAG" \
-H "Authorization: Bearer $SERVICE_ACCOUNT_TOKEN"
# Response: 204 No ContentValidation error contract: creating a customer-managed configuration without its key fields returns 422 with the exact reason in the errors array.
{
"message": "Unprocessable Entity",
"errors": [
"key_resource is required for customer-managed providers"
]
}Related Guides
Tags
Related Resources
No related resources found.