Audit actions¶
The actions sluis records, from the catalogue internal/audit/catalogue/roster.yaml. The trail is explained in audit.
| Term | Meaning |
|---|---|
| Profile | All actions are kept under security, in the installation's tenant @platform |
Delivery async |
Goes on a bounded in-process queue |
Delivery block |
Recorded before the action completes; the action is refused when it cannot be |
| Actor kinds | person, recovery, ci, workload, system, anonymous |
| Target types | client, workspace, organisation, team, github_account, github_app, slack_workspace, slack_channel, slack_user, slack_app, directory_group, directory_user |
Catalogue version 1.23.0, 102 actions.
| Action | Operation | Targets | Delivery | Summary |
|---|---|---|---|---|
roster.person.signed_in |
authentication | client | async | A person signed in to a client, or was refused; at the issuer, with the class of the session it opens (interactive or agent) and that session's deadline. |
roster.recovery.signed_in |
authentication | client | block | Somebody signed in with the recovery identity, which bypasses the directory. |
roster.recovery.disabled |
modify | installation | block | An operator who signed in through the identity provider turned the recovery sign-in off for the whole installation, from the console. Recovery sessions end with it. There is no matching action to turn it on; that is a change of the configuration's recovery.generation. |
roster.access.explained |
access | client | async | An operator looked up what a person, CI job or workload would effectively be granted, or a caller who may not was refused. The record carries counts only. |
roster.token.exchanged |
authentication | client | async | A token was exchanged for one another client accepts, or the exchange was refused. |
roster.github_token.minted |
create | github_app | async | A GitHub App installation token was minted, or refused. Never the token. |
roster.cloudflare.token.minted |
create | cloudflare_preset | async | A Cloudflare API token or R2 credential was minted from a preset's prototype, either stored for the preset (by sluis on its schedule) or on demand for a caller. Never the value. |
roster.cloudflare.token.refused |
create | cloudflare_preset | async | A Cloudflare token was not minted, for a caller who was not granted the preset or because the preset's prototype or the account refused it. |
roster.cloudflare.tokens.swept |
remove | cloudflare_preset | async | sluis deleted the expired Cloudflare tokens it had minted for a preset (only its own, by the ids it recorded). |
roster.cloudflare.token.revoked |
remove | cloudflare_preset | async | Somebody deleted a live Cloudflare token that sluis had minted for a preset. |
roster.backup.completed |
transfer | backup | async | A backup of the installation was written to the archive bucket and its manifest sealed. Counts, and the hashes of the object and sidecar and the fingerprints of the recipients, which a restore requires of the backup it fetches. |
roster.backup.failed |
transfer | backup | async | A backup could not be completed. The records already written stay in the bucket and are not a backup; the next run starts again, and a prune removes them. |
roster.backup.pruned |
remove | backup | async | Backups beyond the retention rule were deleted from the archive bucket (or, with orphans, the objects of runs that never wrote a manifest). |
roster.restore.started |
restore | backup | async | A restore of an installation from a backup began. The module is under maintenance until it completes. unverified is set when an operator went ahead without the backup's sealed record. |
roster.restore.unverified |
restore | backup | block | An operator chose to restore a backup the sealed audit trail does not vouch for (allowUnverified). Recorded before the restore begins, and the restore is refused when it cannot be kept. |
roster.restore.completed |
restore | backup | async | A restore verified against its backup and lifted the maintenance flag. |
roster.restore.failed |
restore | backup | async | A restore did not complete or did not verify. The maintenance flag stays set until an operator looks. |
roster.maintenance.changed |
modify | installation | block | An operator set or lifted the migration freeze (sluis maintenance on or off). While it is set the installation refuses every write of state, answers 503 with Retry-After, and still serves discovery, the key set and a read-only token exchange. Lifting a restore's flag is forced. |
roster.secrets.pruned |
remove | installation | block | An operator ran sluis migrate v5 prune for real. A record with phase started is kept before the first delete and names the layout v4 parameters about to be deleted; the record with phase completed (or a failed outcome) says how many were. Names and counts only, never a value. |
roster.migration.copied |
modify | installation | block | An operator ran sluis migrate v5 copy for real and it had something to write. A record with phase started is kept before the first write and counts what will be written and which differing destination values overwrite replaces (by name); the record with phase completed (or a failed outcome) says how it ended. Names and counts only, never a value. |
roster.secrets.rekeyed |
modify | installation | block | An operator ran sluis secrets rekey for real, re-writing the installation's SSM SecureString parameters under the key secrets.kmsKeyId names. A record with phase started is kept before the first write and names the parameters about to be re-written; the record with phase completed (or a failed outcome) says how many were. Names and counts only, never a value. |
roster.session.ended |
authentication | — | async | A person signed out, ending their sessions, except the agent-class sessions it spared (by client id in spared), which keep running until revoked or their own end. |
roster.session.revoked |
remove | client | async | A person's sessions were revoked, by somebody, or by the issuer (scope refresh_token_reuse) when a spent refresh token was presented again after its grace window, (scope pre_upgrade_cookie, by an anonymous actor) when a browser signed out with a sign-in cookie set before the cookie had a secret of its own, (scope sign_in_replaced, by the person signing in) when another person signed in in the same browser, by the person themselves for one class of their own (scope every_browser_and_app ends every browser sign-in and interactive session and keeps the agent sessions, scope every_agent ends every agent session and keeps the browsers, and ended_class and kept_class say which), or by an operator for one client and every person (scope client_every_identity, no subject). |
roster.session.refresh_refused |
authentication | client | async | A session was refused a refresh because its holder is no longer admitted to the client. |
roster.client.secret.created |
create | client | async | The secret of a generated client was made. |
roster.client.secret.adopted |
create | client | async | An existing secret of a generated client was taken as its stored secret, unchanged. |
roster.client.secret.rotated |
modify | client | async | The secret of a generated client was replaced, the old one staying valid for an overlap. |
roster.client.secret.orphaned |
access | client | async | A stored client secret was found with no generated client of that id in the policy. |
roster.client.secret.deleted |
remove | client | async | The stored secret of a client no longer in the policy was deleted. |
roster.client.secret.denied |
access | client | async | A signed-in caller was refused when managing the secret of a generated client. |
roster.workspace.connected |
create | workspace | async | A directory was connected. |
roster.workspace.reconnected |
modify | workspace | async | A connected directory was given a new consent. |
roster.workspace.disconnected |
remove | workspace | async | A directory was disconnected. |
roster.workspace.domains_changed |
modify | workspace | async | The domains a directory answers for changed. |
roster.workspace.groups_changed |
modify | workspace | async | The groups served from a directory changed. |
roster.github_app.created |
create | github_app, organisation | async | A GitHub App was created for an organisation. |
roster.github_org.connected |
create | organisation | async | A GitHub organisation was connected by installing the App. |
roster.github_org.pass_requested |
modify | organisation | async | An operator asked the GitHub controller to pass over an organisation now. |
roster.github_org.owner_changed |
modify | organisation | async | The directory that owns a GitHub organisation was changed by the installation-wide operator. |
roster.github_org.disconnected |
remove | organisation | async | A GitHub organisation was disconnected. |
roster.github_removals.confirmed |
modify | organisation | async | An operator confirmed a set of removals the safety breaker had held. |
roster.link_app.connected |
create | github_app | async | The App that links people's GitHub accounts was connected. |
roster.link_app.disconnected |
remove | github_app | async | The App that links people's GitHub accounts was disconnected. |
roster.catalogue_app.created |
create | github_app, organisation | async | A catalogued GitHub App was created. |
roster.catalogue_app.installed |
create | github_app, organisation | async | A catalogued GitHub App was installed. |
roster.catalogue_app.disconnected |
remove | github_app, organisation | async | A catalogued GitHub App was disconnected. |
roster.catalogue_app.webhook_changed |
modify | github_app, organisation | async | A step of setting or rotating the secret of a catalogued GitHub App's webhook. |
roster.runner_app.created |
create | github_app, organisation | async | A GitHub App for self-hosted runners was created. |
roster.runner_app.installed |
create | github_app, organisation | async | A GitHub App for self-hosted runners was installed. |
roster.runner_app.disconnected |
remove | github_app, organisation | async | A GitHub App for self-hosted runners was disconnected. |
roster.github_link.created |
create | github_account | async | A person linked their GitHub account. |
roster.github_link.matched |
create | github_account | async | A GitHub account was linked to a person because its profile publishes their work address. |
roster.github_link.imported |
create | github_account | async | An operator imported a link between a GitHub account and a person. |
roster.github_link.moved |
modify | github_account | async | A link moved to another address of the same person. |
roster.github_link.narrowed |
modify | github_account | async | A link lost some of its addresses. |
roster.github_link.unverifiable |
modify | github_account | async | A link could no longer be verified. |
roster.github_link.lost |
remove | github_account | async | A link was lost. |
roster.github_member.invited |
create | organisation, team, github_account | async | A person was invited to a GitHub organisation or team. |
roster.github_member.added |
create | organisation, team, github_account | async | A person was added to a GitHub team. |
roster.github_member.role_set |
modify | organisation, team, github_account | async | A person's role on a GitHub team changed. |
roster.github_member.removed |
remove | organisation, team, github_account | async | A person was removed from a GitHub organisation or team. |
roster.github_member.held |
modify | organisation, team, github_account | async | A change to a person's GitHub membership is held, and needs an operator. |
roster.github_owner.reported |
access | organisation, team, github_account | async | An organisation owner the directory does not vouch for was reported rather than removed. |
roster.slack_workspace.connected |
create | slack_workspace, slack_app | async | A Slack workspace was connected by installing the App. |
roster.slack_workspace.owner_changed |
modify | slack_workspace | async | The directory that owns a Slack workspace was changed by the installation-wide operator. |
roster.slack_workspace.connect_refused |
create | slack_workspace, slack_app | async | An install of the roster's Slack App was refused because it was made into a workspace other than the one first connected. |
roster.slack_workspace.disconnected |
remove | slack_workspace, slack_app | async | A Slack workspace was disconnected. |
roster.slack_app.created |
create | slack_app, slack_workspace | async | A catalogued Slack App was created. |
roster.slack_app.installed |
create | slack_app, slack_workspace | async | A catalogued Slack App was installed into its workspace. |
roster.slack_app.install_refused |
create | slack_app, slack_workspace | async | An install of a catalogued Slack App was refused because it was made into another workspace. |
roster.slack_shared_channel.created |
create | slack_workspace, slack_channel, directory_group, directory_user | async | A Slack Connect channel was defined from the console. |
roster.slack_shared_channel.updated |
modify | slack_workspace, slack_channel, directory_group, directory_user | async | A Slack Connect channel's definition was changed from the console. |
roster.slack_shared_channel.deleted |
remove | slack_workspace, slack_channel, directory_group, directory_user | async | A Slack Connect channel's definition was deleted from the console; the channel stays in Slack. |
roster.slack_console_channel.created |
create | slack_workspace, slack_channel, directory_group, directory_user | async | An ordinary Slack channel was put under management from the console. |
roster.slack_console_channel.updated |
modify | slack_workspace, slack_channel, directory_group, directory_user | async | A console-managed Slack channel's record was changed from the console. |
roster.slack_console_channel.deleted |
remove | slack_workspace, slack_channel, directory_group, directory_user | async | A console-managed Slack channel's record was deleted from the console; the channel stays in Slack. |
roster.slack_channel.created |
create | slack_workspace, slack_channel | async | A Slack channel was created. |
roster.slack_channel.adopted |
modify | slack_workspace, slack_channel | async | An existing Slack channel was adopted into management, by name. |
roster.slack_channel.archived |
modify | slack_workspace, slack_channel | async | An operator archived a Slack channel when forgetting its console record. |
roster.slack_member.invited |
create | slack_workspace, slack_channel, slack_user | async | A person was invited to a Slack channel. |
roster.slack_member.removed |
remove | slack_workspace, slack_channel, slack_user | async | A person was removed from a private Slack channel. |
roster.slack_shared.invited |
create | slack_workspace, slack_workspace, slack_channel | async | A workspace's bot was invited to a shared channel. |
roster.slack_shared.accepted |
modify | slack_workspace, slack_workspace, slack_channel | async | A workspace accepted an invitation to a shared channel. |
roster.slack_action.held |
modify | slack_workspace, slack_channel, slack_user | async | A change to a Slack workspace or channel is held, and needs an operator. |
roster.slack_removals.confirmed |
modify | slack_workspace, slack_channel | async | An operator confirmed a set of Slack removals that were held. |
roster.slack_leaver.reported |
access | slack_workspace, slack_user | async | A person gone from the directory is still an active Slack member; reported rather than acted on. |
roster.outline_workspace.connected |
create | outline_workspace | async | An Outline workspace was connected, or its API key replaced, from the console. |
roster.outline_workspace.disconnected |
remove | outline_workspace | async | An Outline workspace's connection record and API key were removed from the console. |
roster.outline_group.created |
create | outline_workspace, outline_group | async | The Outline controller created a group it manages. |
roster.outline_member.added |
create | outline_workspace, outline_group, outline_user | async | A person was added to an Outline group the controller manages. |
roster.outline_member.removed |
remove | outline_workspace, outline_group, outline_user | async | A person was removed from an Outline group the controller manages. |
roster.outline_role.changed |
modify | outline_workspace, outline_user | async | An Outline account's workspace role was changed. |
roster.outline_collection.created |
create | outline_workspace, outline_collection | async | The Outline controller created a collection the policy binds. |
roster.outline_collection.adopted |
modify | outline_workspace, outline_collection | async | An existing Outline collection came under the controller, recorded once. |
roster.outline_collection.granted |
modify | outline_workspace, outline_group, outline_collection | async | A group was granted a permission on an Outline collection, or its permission changed. |
roster.outline_collection.revoked |
remove | outline_workspace, outline_group, outline_collection | async | A group's grant the policy does not name was removed from a strict Outline collection. |
roster.outline_collection.member_removed |
remove | outline_workspace, outline_collection, outline_user | async | A direct member was removed from a strict Outline collection. |
roster.outline_user.suspended |
modify | outline_workspace, outline_user | async | A leaver's Outline account was suspended. |
roster.outline_user.activated |
modify | outline_workspace, outline_user | async | A suspended Outline account the directory has back was reactivated. |
roster.outline_action.held |
modify | outline_workspace, outline_group, outline_collection, outline_user | async | A change to an Outline workspace is held, and needs an operator. |
roster.outline_breaker.tripped |
modify | outline_workspace | async | A set of Outline removals, demotions or suspensions past its limit was held until an operator confirms it. |
roster.outline_breaker.confirmed |
modify | outline_workspace | async | An operator confirmed a set of Outline changes a breaker held. |