Include SSH key details in Git operation audit events
Related to #599902 (closed) and supersedes the draft exploration !237337 (closed)
What does this MR do and why?
-
Adds the SSH key used for authentication to the streamed
repository_git_operationaudit event message:gl_key_type(keyfor user SSH keys,deploy_keyfor deploy keys) andgl_key_id. -
This lets organizations relying on SAML/group membership with standard GitLab.com accounts correlate Git-over-SSH activity with a specific credential for compliance and incident response. It is the alternative agreed in the issue, instead of surfacing
add_ssh_key/remove_ssh_keyat group scope for non-enterprise users, which would expose personal credential data without administrative ownership of the account. See: -
Both event emitters merge
GitAccessActor#key_detailsinto the message:API::Internal::Shellhorse(POST /internal/shellhorse/git_audit_event) and the legacy path inAPI::Internal::Base(POST /internal/allowed, used when thelog_git_streaming_audit_eventsfeature flag is disabled). See sequence diagram. -
key_detailsreturns{}when the actor is not key-backed (for example, HTTP with username/password or a deploy token), so those events are unchanged. This behaviour is already covered by unit specs inspec/lib/api/support/git_access_actor_spec.rb. -
No gitlab-shell changes are needed. Rails has resolved
key_idinto the acting key since !37289 (merged), and gitlab-shell sendskey_idto the audit endpoint since v14.49.0 (gitlab-shell!1411 (merged)).masterpinsGITLAB_SHELL_VERSION14.56.1. Older gitlab-shell omitskey_id, and those events simply carry no key fields.
Documentation Review
See !244631 (merged)
Screenshots or screen recordings
| After |
|---|
How to set up and validate locally
repository_git_operationis a streaming-only audit event (not saved to the database), so it must be verified at a streaming destination, not in the Audit events UI (see original git audit streaming events implementation MR).NB: the steps below use this concrete setup, adjust names to your own GDK: top-level group
enterprise-users, projectenterprise-users/ent_proj, test useraud.
-
Update gitlab-shell. Your local gitlab-shell must be v14.49.0 or later to send
key_idto the audit endpoint (added in gitlab-shell!1411 (merged); see gitlab-shell CHANGELOG). Older versions send onlyusername, and the event will show no key fields:cd <gdk-root> # e.g. ~/gitlab-development-kit make gitlab-shell-update gdk restart sshd cat gitlab-shell/VERSION # must print >= 14.49.0 (14.56.1 at time of writing) -
Enable SSH in GDK (GDK SSH how-to;
gitlab-sshdlistens on127.0.0.1:2222by default):gdk config set sshd.enabled true gdk reconfigure && gdk restart -
Simulate SaaS (docs). This matches the GitLab.com scenario from the issue: set
GITLAB_SIMULATE_SAAS=1(for example, viagdk.yml) and restart GDK. Then enable Admin > Settings > General > Account and limit > Allow use of licensed EE features, and in Admin > Overview > Groups, edit the top-level groupenterprise-usersand set its Plan toUltimate. -
Set up the streaming destination. Create a request bin, for example at https://requestcatcher.com, and keep its inspection page open (only use this with synthetic GDK test data). Then in the top-level group
enterprise-users, go to Secure > Audit events > Streams and add an HTTP streaming destination pointing at the request bin URL. Events stream to the root group's destinations, so this must be on the top-level group, not a subgroup or the project. -
Create the test user and their SSH key. Create user
aud, add them with Developer access toenterprise-users/ent_proj. Generate a dedicated keypair. A fresh key is required, because GitLab rejects public keys already registered to another account, such as root's:ssh-keygen -t ed25519 -f ~/.ssh/gdk_aud_key -N "" cat ~/.ssh/gdk_aud_key.pub # copy the whole output line (ssh-ed25519 AAAA... comment)Signed in as
aud, paste it into the Key field at User Settings > SSH Keys and select Add key. -
Positive case (user SSH key): clone (or push) over SSH, forcing the
audkey so the SSH agent cannot offer a key registered to another user (IdentitiesOnly=yes, see use different keys for different repositories, applied for a single invocation withgit -c). Accept the host key fingerprint prompt on first connect. Therm -rf ent_projmakes the step easy to re-run:rm -rf ent_proj git -c core.sshCommand="ssh -o IdentitiesOnly=yes -i ~/.ssh/gdk_aud_key" clone ssh://git@127.0.0.1:2222/enterprise-users/ent_proj.gitExpected: the request bin page shows an incoming
repository_git_operationrequest whosedetails.custom_messageincludes"gl_key_type": "key"and a"gl_key_id". -
Positive case (deploy key): a deploy key is also a keypair generated on your machine. The UI only stores the public half. Generate one and add it to the project at Settings > Repository > Deploy keys (paste the
.publine):ssh-keygen -t ed25519 -f ~/.ssh/gdk_deploy_key -N "" cat ~/.ssh/gdk_deploy_key.pub # paste into Settings > Repository > Deploy keysClone with that key:
rm -rf ent_proj git -c core.sshCommand="ssh -o IdentitiesOnly=yes -i ~/.ssh/gdk_deploy_key" clone ssh://git@127.0.0.1:2222/enterprise-users/ent_proj.gitExpected: the request bin page shows an incoming request whose
details.custom_messageincludes"gl_key_type": "deploy_key"and a"gl_key_id".
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.