BUILDING Parts of this page describe what is not built yet, and each says so.
The audit vocabulary
Every entry in your audit log says who did something, what they did and to what. The words it uses are a closed set, and a rule that matches them keeps matching. This page lists them. To check that a copy of the log is intact, see Verify your audit log.
Who did it
An entry’s actor_kind is one of six words, and there is no seventh. Filter on
it, or on actor_id, to see what one kind of actor did.
| actor_kind | Who | actor_id is |
|---|---|---|
user | A person signed in to the console or the command line. | The person’s id. |
token | An API token acting for the person who made it. | The token’s id. |
agent | One of the platform’s agents. | The agent’s name. |
system | The control plane acting on its own: schedulers, reconcilers and expiry sweeps. | The component’s name. |
staff | A member of RunningLake’s operator team acting on your organisation. Filter on it to see every action we took. | The staff member’s id. |
service | A service principal, a project’s machine identity, acting as itself. | The principal’s id. |
What was done
An entry’s action is a dotted phrase such as principal.credential.revoke,
and its resource_kind and resource_id name what it was done to. Match an
action exactly: the console’s filters are exact too, with no prefixes, so that a rule for one
action never fires on another whose name begins the same way. An action you have not seen before
is a new kind of thing happening, not a variant of one you have.
The entry’s before and after values are the canonical JSON that was hashed. They never hold a secret: a service principal’s secret is shown once when it is made and is not written to the log.
The door a machine came through
A service principal is the actor of what a machine does, and its id does not change when a secret
is rotated. An entry written through one also says which door it used. That is the
via_json field of the entry: a JSON object, empty for an entry with no door. It is
returned by the audit log and written into an export, and an entry that carries one is hashed as
version 2 of the encoding; an export that holds one is written as file version 2. To check a copy, see
Verify your audit log.
Every value is text, including a provider’s numbers and booleans. A key that is not in the
tables below is never written. A person is never named in it: there is no actor,
actor_id or user_login in a door, because none is needed to say which door was used.
The one id of a person a door holds is on_behalf_of, on the entries of an agent (below), and it is an id,
never a name or an address.
The door
| Key | It holds |
|---|---|
credential_kind | How the credential got in: secret for a service principal’s secret, federated for a token a CI job exchanged, webhook for a webhook delivery, token for an API token. |
credential_id | The id of that credential, written whenever credential_kind is. |
An entry for a change to a pipeline draft that a person made with an API token carries the token door: credential_kind is token and
credential_id is the token’s id. The person is still the actor of the entry. A change made with a signed-in session carries no door. Like every entry with a door,
it is hashed as version 2, so an export of a stretch of the log that holds one needs a client that reads version 2 (the rl command line does).
An agent acting for a person
The actor of an entry an AI agent writes is the agent. It also says which token the agent came through, with the
token door above, and for whom it acted:
| Key | It holds |
|---|---|
on_behalf_of | The id of the person the agent acts for: the person whose role the agent is never above. Today that is the person who made the agent’s token. |
A CI exchange
An entry written through an exchanged token adds policy_id, the trust policy that
matched. The entry of the exchange itself, principal.federate, also carries the claims
that were verified, and only the ones that are about a place and a run:
| Key | It holds |
|---|---|
policy_id | The id of the trust policy that matched. |
issuer | The CI system’s issuer. |
repository_id, repository_owner_id, repository | GitHub: the repository and its owner, by immutable number and by name. |
ref, ref_protected, environment, event_name | The ref, whether it is protected, the environment and the event that started the job. |
workflow_ref, job_workflow_ref | The workflow, and the reusable workflow the job ran. |
run_id, run_attempt, sha | The run, its attempt and the commit. |
namespace_id, project_id, project_path, pipeline_source | GitLab’s names for the same things. |
Keys nothing writes yet
The tables on this page are the whole vocabulary, and two keys of it have no writer.
| Key | It will hold |
|---|---|
endpoint_id, trigger, delivery_id | A webhook delivery: the endpoint, the trigger it started and the delivery. |
agent_task | An agent acting for a person: the task it runs. The control plane writes it for an agent that comes in through a task’s own token; no gateway issues one yet. |
No entry carries a webhook key yet.
No entry carries agent_task yet.
Service principals
These actions are written when a service principal, its secrets or its CI trust are managed, when a CI job exchanges its identity for a token, and when a secret is about to expire. An entry for a principal or for one of its secrets names the project it belongs to.
| action | resource_kind | It means |
|---|---|---|
principal.create | ServicePrincipal | Created a service principal. |
principal.update | ServicePrincipal | Changed a service principal’s name, grants or targets. |
principal.disable | ServicePrincipal | Disabled a service principal, which closes every door of it at once. |
principal.enable | ServicePrincipal | Enabled a disabled service principal. |
principal.delete | ServicePrincipal | Deleted a disabled service principal. |
principal.credential.create | PrincipalCredential | Made a secret for a service principal. |
principal.credential.rotate | PrincipalCredential | Replaced a service principal’s secret with a new one. |
principal.credential.revoke | PrincipalCredential | Revoked a service principal’s secret. |
principal.trust_policy.create | TrustPolicy | Trusted a CI system to act as a service principal. |
principal.trust_policy.delete | TrustPolicy | Stopped trusting a CI system for a service principal, and revoked the tokens it had been given. |
principal.trust_policy.disable | TrustPolicy | Switched off a CI trust policy, and revoked the tokens it had been given, because the person who wrote it was banned from the platform. It is written by the system, and the entry names the policy, the principal, the person, the reason and the tokens revoked. |
principal.trust_policy.enable | TrustPolicy | Switched a CI trust policy back on after an owner read it. The entry says why it had been off. |
principal.credential.expiring | PrincipalCredential | Warned that a service principal’s secret is about to expire. It is written 14 days and again 3 days before, once each, by the system, and the entry says which. |
principal.federate | PrincipalCredential | Exchanged a CI job’s identity token for a short-lived token of a service principal. The entry carries the claims that were verified. |
principal.webhook_endpoint.create | WebhookEndpoint | Made a webhook endpoint for a service principal, bound to a trigger of one pipeline in one environment. The entry names the endpoint and when it expires, and never its signing secret. |
principal.webhook_endpoint.rotate | WebhookEndpoint | Made a new signing secret for a webhook endpoint. The older one keeps verifying until the end of the overlap the entry names. |
principal.webhook_endpoint.revoke_version | WebhookEndpoint | Stopped an older signing secret of a webhook endpoint before its overlap ended. |
principal.webhook_endpoint.disable | WebhookEndpoint | Disabled a webhook endpoint and stopped every signing secret it had. |
Sign-in and domains
These actions are written when your organisation connects or removes its own identity provider, when people are carried across to a provider you connected again, when a person’s sign-in is linked to their account, and when an email domain is claimed, proved or lost. A sign-in entry never holds an address or the provider’s identifier for a person: it holds counts and ids.
| action | resource_kind | It means |
|---|---|---|
identity.provider.create | IdentityProvider | Connected the organisation’s own identity provider. The entry carries its name, issuer and client id, and no secret. |
identity.provider.disable | IdentityProvider | Removed an identity provider of the organisation. Every session it had signed in was ended, and any carry-over chosen for it ended with it. The entry carries how many sessions were ended. Its actor is your owner, a member of our staff acting on your organisation, or our operator command, which acts as system. |
identity.provider.enable | IdentityProvider | Switched a removed identity provider back on. Only our operator command does this; an owner who removed a provider connects the issuer again instead. |
identity.link | UserIdentity | Linked a person’s sign-in at a provider to their account. linked_by says how it was authorised: invitation, session_link (someone already signed in attached another provider), carry_over, or jit (the person joined through the organisation’s own identity provider with no invitation; that sign-in did not prove their address, so a stronger proof of it takes the account over). |
identity.address_reclaimed | User | A sign-in that proved an email address took over an account whose sign-ins had never proved it. Those sign-ins, and every session and API token of that person in every organisation, were ended; their memberships stay. It is written in the chain of each organisation the person belongs to. |
idp.carry_over.start | OrgProvider | An owner chose people to carry across to a provider connected again. The entry carries how many were chosen, whether the choice was everyone eligible or a list, and when their chance ends. |
idp.carry_over.end | OrgProvider | An owner ended a carry-over. People already carried stay carried. |
idp.carry_over.use | OrgProvider | A chosen person signed in through the provider and was carried across: their sign-in was linked to their account, and their one chance was spent. The entry carries the provider and the person’s id. |
idp.jit.enable | OrgProvider | An owner opened the organisation’s own identity provider to people nobody invited. They join as guests, who can see nothing until an owner gives them a role. The entry carries the domains it covers, the most people who may join that way (the ceiling) and the attestation the owner agreed to, word for word. Turning this on needs a fresh sign-in by a person; no token can. |
idp.jit.update | OrgProvider | An owner changed the domains or the ceiling of a provider that is already open. The entry carries the state before and after. Adding a domain or raising the ceiling needs a fresh sign-in by a person and carries the attestation again; removing a domain or lowering the ceiling needs none. |
idp.jit.disable | OrgProvider | An owner closed the provider to people nobody invited. People who already joined stay members. The entry carries the state it had. Removing the provider closes it too, in the entry that removes it. |
idp.jit.refused | OrgProvider | Written only for an organisation that has let people join through its own identity provider: a person was turned away because the organisation already holds the most people it allows to join that way. At most one an hour per organisation. It carries the provider and the limit, and names nobody. |
org.domain.claim | OrgDomain | Claimed an email domain for the organisation. It admits nobody until its DNS record is proved. |
org.domain.remove | OrgDomain | Removed a domain claim. The entry says whether it had been proved. |
org.domain.release | OrgDomain | Moved a verified claim back to pending. The entry says why. |
org.domain.verify | OrgDomain | A check found the DNS record of a pending claim, or found a lapsed claim’s record again, and the claim admits its domain’s emails from now. |
org.domain.failing | OrgDomain | A check could no longer find a verified claim’s DNS record. The claim keeps admitting for 7 days; the entry carries the instant it stops, admits_until. |
org.domain.recover | OrgDomain | A failing claim’s record was back within its 7 days, and the claim is verified again. |
org.domain.lapse | OrgDomain | A failing claim’s record was still gone at the end of its 7 days. The claim is pending again and admits nobody until it is proved again. |
Support access
These actions are written when you let RunningLake support into your organisation, when you end that, when a staff member enters it, and when they read something under it. One thing can be read through a grant today: a pipeline run’s record (its project, environment and pipeline names, its state, and each task’s name and state). A run’s logs and a table’s schema cannot be read through a grant. Each read is an entry that says what kind of thing was read and its id, never what it held.
Staff can also ask to read without your consent, which is called break-glass. A staff member asks, with a reason you can read, and the entry below is written the moment they ask, before anything is read. A different staff member must approve it, and then only the person who asked can read, for one hour, through the same list of reads. No email is sent when it is asked. Our security page says what staff can still do without asking.
| action | resource_kind | It means |
|---|---|---|
supportsession.grant | SupportGrant | Allowed RunningLake support to enter your organisation for 1, 4 or 24 hours. The actor is the person who gave it, who confirmed it was them in the last five minutes. The entry carries the grant’s id, its length, when it runs out, and the sentence they gave. |
supportsession.end | SupportGrant | Ended a grant at once. The actor is whoever ended it: a person, or an API token of an owner or an admin. The entry carries when, and how many staff members had entered it. |
supportsession.enter | SupportGrant | A staff member entered a live grant. The actor_kind is staff, and the entry carries their display name and when the grant runs out. Entering reads nothing by itself. |
supportsession.read | SupportGrant or SupportBreakglass | A staff member read a pipeline run’s record, under a live grant they had entered (SupportGrant) or under a break-glass session (SupportBreakglass). The actor_kind is staff. The entry carries the id of the grant or of the break-glass session, the kind of thing read (a run) and the run’s id, and never the run itself. Only a signed-in staff member writes one: one who entered a live grant, or the person who asked for break-glass. It is written before anything is read, so a read that cannot be recorded does not happen. Asking for a run that does not exist is also an entry. |
supportsession.breakglass.ask | Org | A staff member asked to read your organisation’s data without your consent. It is written the moment they ask, before anything is read. The actor_kind is staff, and the entry carries the sentence they gave, their display name and the id of the request. Nothing is read until a different staff member approves it, and it lapses if nobody does. |
supportsession.breakglass.approve | SupportBreakglass | A different staff member approved a break-glass request. The actor_kind is staff, and the entry carries the approver’s display name, who asked, the id of the request and when the one hour runs out. Only the person who asked can read, until then. |