Skip to content

Audit Events ​

Which API routes write an entry to the audit log, and with what. Every route that can change state (POST, PUT, PATCH, DELETE) is classified in apps/api/audit_coverage.yaml; the test suite fails when a route is missing from it or an entry names a route that no longer exists, and the known gaps list may only shrink. Values come from the vocabulary reference.

Audited routes ​

Snapshot says which states the entry records: the object before the change, after it, both (an update, so the entry carries a field-level diff), or none (the entry's details describe the event instead). A route listing more than one resource type records a different object on some path — a schedule occurrence that produced no run is recorded on the schedule.

MethodPathResource typeActionsSnapshot
POST/binary-artifacts/bulk-deletebinary_artifactpurgeboth
DELETE/binary-artifacts/{artifact_id}binary_artifactpurgeboth
POST/file-repositories/ensure-defaultfile_repositorycreateafter
POST/file-repositories/{file_repository_id}/foldersfile_repository_foldercreateafter
POST/file-repositories/{file_repository_id}/folders/renamefile_repository_folderrenameboth
DELETE/file-repositories/{file_repository_id}/foldersfile_repository_folderdeletebefore
POST/files/{file_id}/movestored_filemoveboth
POST/audit-logs/cleanupaudit_logprunenone
POST/api-tokenspersonal_access_tokencreateafter
DELETE/api-tokens/by-user/{username}personal_access_tokenrevokenone
DELETE/api-tokens/{token_id}personal_access_tokenrevokenone
POST/approvals/{approval_id}/decisionapprovalapprove, rejectboth
POST/config-exchange/operationsconfig_exchangeexport, import, plan, applyboth
POST/devicesdevicecreateafter
POST/devices/bulk/deletedevicesoft_deletebefore
POST/devices/bulk/permanentdevicepermanent_deletebefore
POST/devices/bulk/restoredevicerestorenone
DELETE/devices/{device_id}devicesoft_deletebefore
PUT/devices/{device_id}deviceupdateboth
PATCH/devices/{device_id}/overlaydeviceannotateboth
POST/devices/{device_id}/duplicatedeviceduplicateafter
DELETE/devices/{device_id}/permanentdevicepermanent_deletebefore
POST/devices/{device_id}/restoredevicerestoreafter
POST/file-repositoriesfile_repositorycreateafter
DELETE/file-repositories/{file_repository_id}file_repositorydeletebefore
PATCH/file-repositories/{file_repository_id}file_repositoryupdateboth
POST/registry-credentialsregistry_credentialcreateafter
PATCH/registry-credentials/{credential_id}registry_credentialupdateboth
DELETE/registry-credentials/{credential_id}registry_credentialdeletebefore
DELETE/images/repositorycontainer_imagedeletebefore
DELETE/images/repository/tagcontainer_imagedeletebefore
DELETE/platform/images/repositorycontainer_imagedeletebefore
DELETE/platform/images/repository/tagcontainer_imagedeletebefore
POST/file-repositories/{file_repository_id}/files/importstored_fileimportafter
POST/file-repositories/{file_repository_id}/files/uploadstored_fileupload, restoreafter
POST/file-repositories/{file_repository_id}/set-defaultfile_repositoryset_defaultboth
DELETE/files/{file_id}stored_filepermanent_deletebefore
POST/flowsflowcreateafter
DELETE/flows/{flow_id}flowsoft_deletebefore
PUT/flows/{flow_id}flowupdateboth
POST/flows/{flow_id}/attachmentsflow_attachmentcreateafter
POST/flows/{flow_id}/attachments/bulkflow_attachmentbulk_create, create, updateafter
POST/flows/{flow_id}/attachments/bulk-renameflow_attachmentbulk_rename, renameboth
DELETE/flows/{flow_id}/attachments/folderflow_attachmentdeletebefore
DELETE/flows/{flow_id}/attachments/{attachment_id}flow_attachmentdeletebefore
PATCH/flows/{flow_id}/attachments/{attachment_id}flow_attachmentupdateboth
POST/flows/{flow_id}/commitflowcommitnone
PATCH/flows/{flow_id}/gitflowlink_git, clear_git, update_git, detach_gitboth
POST/flows/{flow_id}/git/detachflowdetach_gitboth
PATCH/flows/{flow_id}/pinflowupdateboth
PATCH/flows/{flow_id}/manual-runsflowupdateboth
DELETE/flows/{flow_id}/permanentflowpermanent_deletebefore
POST/flows/{flow_id}/draftflowupdateboth
POST/flows/{flow_id}/duplicateflowduplicateafter
POST/flows/{flow_id}/notifications/subscriptionsflow_notification_subscriptioncreateafter
PATCH/flows/{flow_id}/notifications/subscriptions/{subscription_id}flow_notification_subscriptionupdateboth
DELETE/flows/{flow_id}/notifications/subscriptions/{subscription_id}flow_notification_subscriptiondeletebefore
POST/flows/{flow_id}/push-to-gitflowexportnone
POST/flows/{flow_id}/restoreflowrestoreafter
POST/flows/{flow_id}/restore/{version}flowrestoreboth
POST/flows/{flow_id}/revert-draftflowrestoreboth
POST/flows/{flow_id}/sync-from-gitflowsyncnone
POST/git-repositories/{repo_id}/syncgit_repositorysyncnone
POST/platform-sync/profilesplatform_sync_profilecreateafter
PATCH/platform-sync/profiles/{profile_id}platform_sync_profileupdateboth
DELETE/platform-sync/profiles/{profile_id}platform_sync_profilesoft_deleteboth
POST/git-repositoriesgit_repositorycreateafter
DELETE/git-repositories/{repo_id}git_repositorysoft_deletebefore
PATCH/git-repositories/{repo_id}git_repositoryupdateboth
POST/hooks/{path_token}webhook_endpointtriggerafter
POST/internal/schedules/{schedule_id}/triggerrun, schedulestartafter
PATCH/internal/approvals/{approval_id}approvalapprove, reject, expire, cancel, updateboth
POST/internal/runs/{run_id}/approvalsapprovalrequestafter
POST/inventory/providersinventory_provider_configcreateafter
DELETE/inventory/providers/{provider_id}inventory_provider_configsoft_deleteboth
PATCH/inventory/providers/{provider_id}inventory_provider_configupdateboth
DELETE/inventory/providers/{provider_id}/permanentinventory_provider_configpermanent_deletebefore
POST/inventory/providers/{provider_id}/purge-inventoryinventory_provider_inventorypurgeboth
POST/inventory/providers/{provider_id}/restoreinventory_provider_configrestoreboth
POST/inventory/providers/{provider_id}/syncinventory_provider_configsyncafter
POST/inventory/providers/{provider_id}/discoverinventory_provider_configdiscoverboth
GET/inventory/object-typesinventory_provider_configdiscoverboth
POST/notifications/destinationsnotification_destinationcreateafter
DELETE/notifications/destinations/{destination_id}notification_destinationsoft_deletebefore
PATCH/notifications/destinations/{destination_id}notification_destinationupdateboth
POST/notifications/destinations/{destination_id}/duplicatenotification_destinationduplicateafter
DELETE/notifications/destinations/{destination_id}/permanentnotification_destinationpermanent_deletebefore
POST/notifications/destinations/{destination_id}/restorenotification_destinationrestoreboth
POST/notifications/destinations/{destination_id}/testnotification_destinationtestafter
POST/orgsorganizationcreateafter
DELETE/orgs/{org_ref}organizationdeletebefore
PATCH/orgs/{org_ref}organizationupdateboth
POST/orgs/{org_ref}/idp-mappingsorg_idp_mappingcreateafter
DELETE/orgs/{org_ref}/idp-mappings/{mapping_id}org_idp_mappingdeletebefore
PATCH/orgs/{org_ref}/idp-mappings/{mapping_id}org_idp_mappingupdateafter
POST/orgs/{org_ref}/membersorg_membershipcreateafter
DELETE/orgs/{org_ref}/members/{user_id}org_membershipdeletebefore
PATCH/orgs/{org_ref}/members/{user_id}org_membershipupdateboth
POST/platform-sync/profiles/{profile_id}/applyplatform_sync_profileapplynone
POST/platform-sync/profiles/{profile_id}/conflicts/{change_id}/resolveplatform_sync_planresolvenone
POST/platform-sync/profiles/{profile_id}/destructive-authorizationsplatform_sync_destructive_authorizationcreatenone
POST/platform-sync/profiles/{profile_id}/destructive-authorizations/{authorization_id}/revokeplatform_sync_destructive_authorizationrevokenone
POST/platform-sync/profiles/{profile_id}/exportplatform_sync_profileexportnone
POST/platform-sync/profiles/{profile_id}/planplatform_sync_profileplannone
POST/runsrunstartafter
DELETE/runs/{run_id}runsoft_deletebefore
PATCH/runs/{run_id}runupdateboth
POST/runs/{run_id}/approvals/{approval_id}/decisionapprovalapprove, rejectboth
POST/runs/{run_id}/cancelruncancelboth
POST/runs/{run_id}/pauserunpauseboth
DELETE/runs/{run_id}/permanentrunpermanent_deletebefore
POST/runs/{run_id}/restorerunrestoreafter
POST/runs/{run_id}/resumerunresumeboth
POST/schedulesschedulecreateafter
DELETE/schedules/{schedule_id}schedulesoft_deletebefore
PATCH/schedules/{schedule_id}scheduleupdateboth
DELETE/schedules/{schedule_id}/permanentschedulepermanent_deletebefore
POST/schedules/{schedule_id}/restoreschedulerestoreafter
POST/schedules/{schedule_id}/runrunstartafter
POST/secretssecretcreateafter
DELETE/secrets/{secret_id}secretdeletebefore
PATCH/secrets/{secret_id}secretupdateboth
DELETE/settings/permissions/actions/overridepermission_action_overridedeletebefore
DELETE/settings/permissions/overridepermission_overridedeletebefore
PUT/settings/permissions/actions/overridepermission_action_overridecreate, updateboth
PUT/settings/permissions/overridepermission_overridecreate, updateboth
POST/settings/secrets-backendssecret_backendcreateafter
DELETE/settings/secrets-backends/{backend_id}secret_backenddeletebefore
PATCH/settings/secrets-backends/{backend_id}secret_backendupdateboth
POST/sitessitecreateafter
POST/sites/bulk/deletesitesoft_deletebefore
POST/sites/bulk/permanentsitepermanent_deletebefore
POST/sites/bulk/restoresiterestorenone
DELETE/sites/{site_id}sitesoft_deletebefore
PATCH/sites/{site_id}siteupdateboth
POST/sites/{site_id}/duplicatesiteduplicateafter
DELETE/sites/{site_id}/permanentsitepermanent_deletebefore
POST/sites/{site_id}/restoresiterestoreafter
DELETE/tf-states/{name}tf_statedeletebefore
POST/tf-states/{name}/force-unlocktf_stateunlockafter
DELETE/tf-states/{name}/locktf_stateunlockafter
POST/tf-states/{name}/rollbacktf_staterollbackboth
POST/tf-states/{name}/importtf_stateimportafter
POST/tf-states/{name}/statetf_stateupdateafter
GET/tf-states/{name}/versions/{version}/contenttf_stateexportafter
POST/variablesvariablecreateafter
DELETE/variables/{variable_id}variablesoft_deletebefore
PATCH/variables/{variable_id}variableupdateboth
DELETE/variables/{variable_id}/permanentvariablepermanent_deletebefore
POST/variables/{variable_id}/restorevariablerestoreafter
POST/webhookswebhook_endpointcreateafter
DELETE/webhooks/{webhook_id}webhook_endpointsoft_deletebefore
PATCH/webhooks/{webhook_id}webhook_endpointupdateboth
DELETE/webhooks/{webhook_id}/permanentwebhook_endpointpermanent_deletebefore
POST/webhooks/{webhook_id}/restorewebhook_endpointrestoreafter
POST/webhooks/{webhook_id}/rotate-secretwebhook_endpointrotateboth

Exempt routes ​

Routes that change nothing durable, or whose effects another record already captures (run events, monitor samples). Each carries its reason.

MethodPathReason
POST/api/v1/monitor-samples/batchhigh-volume worker telemetry; the monitor samples themselves are the record
POST/api/v1/monitorsworker monitor lifecycle; run_events and the monitor rows are the record
PATCH/api/v1/monitors/{monitor_db_id}worker monitor lifecycle; run_events and the monitor rows are the record
POST/api/v1/monitors/finalize-for-run/{run_id}worker monitor lifecycle; run_events and the monitor rows are the record
POST/auth/bff/ticketshort-lived stream ticket; the stream's target resource is audited on its own routes
POST/binary-artifacts/bulk-downloadread-only download (POST carries the id list)
POST/config-exchange/operations/{correlation_id}/cancelalways answers 409; nothing changes
POST/file-repositories/{file_repository_id}/test-connectionconnectivity probe; only last_connected_at bookkeeping changes
POST/registry-credentials/{credential_id}/testlogin probe; only last_connected_at bookkeeping changes
POST/files/{file_id}/device-download-urlread-only presigned URL issuance
POST/files/{file_id}/download-urlread-only presigned URL issuance
POST/flows/{flow_id}/interface/optionsread-only query carried in a POST body
POST/flows/{flow_id}/interface/preview-resolveread-only dry run
POST/flows/{flow_id}/interface/validateread-only validation
POST/flows/{flow_id}/validateread-only validation
POST/git-repositories/{repo_id}/test-connectionconnectivity probe; only last_connected_at bookkeeping changes
POST/internal/maintenance/tickruns the maintenance jobs; each job audits its own effects
PATCH/internal/runs/{run_id}worker run lifecycle; run_events is the record
POST/internal/runsengine-spawned subflow run; the parent run's start entry and run_events are the record
POST/internal/runs/{run_id}/artifactsworker run lifecycle; run_events is the record
POST/internal/runs/{run_id}/artifacts/uploadworker run lifecycle; run_events is the record
POST/internal/runs/{run_id}/assign-shared-workerworker placement bookkeeping; run_events is the record
POST/internal/runs/{run_id}/cancelengine-initiated cancellation cascade; run_events is the record (user cancellations are audited on POST /runs/{run_id}/cancel)
POST/internal/runs/{run_id}/eventsworker run lifecycle; run_events is the record
PUT/internal/runs/{run_id}/run-varsworker run lifecycle; run_events is the record
POST/internal/runs/{run_id}/step-runsworker run lifecycle; run_events is the record
POST/internal/runs/{run_id}/tf-state-accessissues a step's short-lived token for one state; what the step does with it is audited on the state routes, naming the run
DELETE/internal/runs/{run_id}/tf-state-access/{token_id}revokes a step's short-lived token early; the run's end revokes it anyway
POST/internal/runs/{run_id}/registry-accessissues a container step's short-lived registry token; what the step pulls or caches is in its run events
DELETE/internal/runs/{run_id}/registry-access/{token_id}revokes a step's short-lived registry token early; the run's end revokes it anyway
PATCH/internal/step-runs/{step_run_id}worker run lifecycle; run_events is the record
POST/internal/runtime/env-keysin-process registry; nothing durable changes
DELETE/internal/runtime/env-keys/{worker_id}in-process registry; nothing durable changes
POST/internal/workers/heartbeatliveness only; nothing durable changes
POST/inventory/providers/{provider_id}/test-connectionconnectivity probe; only last_tested_* bookkeeping changes
POST/tf-states/{name}/locktransient coordination held for one plan or apply; the version it writes and any force unlock are audited
POST/notifications/destinations/test-configread-only probe of a submitted config
POST/schedules/validate-cronread-only validation
POST/secrets/{secret_id}/duplicatenot implemented; answers 501
POST/settings/secrets-backends/{backend_id}/testconnectivity probe; nothing changes
POST/variable-contextsread-only query carried in a POST body
POST/variable-contexts/validateread-only validation
POST/webhooks/{webhook_id}/testread-only validation

Known gaps ​

Routes that change state and do not record an entry yet. Each names the change that closes it; this list only shrinks.

MethodPathClosing change

Released as open source under the AGPL-3.0-or-later license. Development is sponsored by Rexonix s.r.o.. Contact — [email protected].