# GitLab event onboarding

> Inspect and configure project-scoped GitLab job and pipeline event delivery through the API or CLI.

Source: https://docs.realhw.dev/guides/gitlab-webhook/
Documentation index: https://docs.realhw.dev/llms.txt

GitLab job events create durable demand that can start cold RealHW capacity. A runner
registration alone does not establish event delivery. CLI 0.4.0 adds the commands below;
check `realhw capabilities --json` for server support before applying changes. A 404
means the matching API has not been deployed. The retired Rust CLI has no onboarding
support; use the Python `realhw-cli` repository.

## Customer workflow

Use an existing runner UUID from `realhw runners list --account-id ACCOUNT_UUID`.
Inspection requires `runners:read`; configuration requires `runners:write` and the
registration's account/project scope. Browser login defaults to read-only permissions.
Request the necessary permissions explicitly or provision a restricted API key.

```sh
realhw capabilities --json
realhw runners webhook inspect RUNNER_UUID --json
realhw runners webhook configure RUNNER_UUID --reason 'Enable pending-job demand' --json
realhw runners webhook configure RUNNER_UUID --reason 'Enable pending-job demand' --apply --json
```

Configure defaults to preview: it reads GitLab but does not create/update a hook or
persist a supplied credential. It records an audit operation, including previews and
failures. Review the callback, action, blockers, and limitations before applying.
An apply creates one hook or updates the existing exact-callback hook in place. Multiple
matching hooks block the operation; unrelated hooks are left intact.

If the registration has no usable stored project API credential, inject a token from
your secret manager into an environment variable, then name that variable:

```sh
realhw runners webhook configure RUNNER_UUID --reason 'Restore project event delivery' \
  --gitlab-token-env PROJECT_GITLAB_TOKEN --json
realhw runners webhook configure RUNNER_UUID --reason 'Restore project event delivery' \
  --gitlab-token-env PROJECT_GITLAB_TOKEN --apply --json
```

Never put the token value in an argument, prompt, JSON file, or documentation. GitLab
requires project read access and sufficient API permissions/role to manage hooks
(normally Maintainer). Successful apply encrypts the supplied project credential for
subsequent job metadata reads. Failed apply and preview do not replace it. Tokens are
never returned. Use the narrowest project-scoped token GitLab supports.

## Operator workflow

Set `REALHW_OPS_API_BASE` and `REALHW_OPS_TOKEN` through your approved secret environment.
Ops commands never fall back to customer credentials and read the Ops policy before
webhook operations.

```sh
realhw ops policy --json
realhw ops runners webhook inspect RUNNER_UUID --json
realhw ops runners webhook configure RUNNER_UUID --reason 'Restore event onboarding' --json
realhw ops runners webhook configure RUNNER_UUID --reason 'Restore event onboarding' --apply --json
```

The customer endpoints are `GET` and `POST`
`/api/v1/virtual-runners/{runner_id}/gitlab-webhook`. Typed Ops equivalents use
`/admin/realhw/virtual-runners/{runner_id}/gitlab-webhook`. POST accepts `reason`,
`dry_run` (defaults true), and optional write-only `gitlab_access_token`. Configure
returns `operation_id`, `dry_run`, `action` (`create` or `reconcile`), and `status`.
Rust DTOs generate the browser contract; the Python client preserves the API JSON.

## Delivery and recovery

RealHW derives a per-project hook verifier from its server-only root. Only the derived
verifier goes to that project's GitLab instance. The receiver continues accepting
retained legacy verifiers during migration. The callback is derived from the trusted
server `REALHW_GITLAB_WEBHOOK_ORIGIN` HTTPS origin, never from a request Host header. The dashboard origin may be IP restricted and must not be used here. Operators must
ensure that the configured public API origin routes `/api/v1/gitlab/webhooks/` to this API.

A successful configuration means provider readback verified the hook identity, job and
pipeline subscriptions, enabled status and TLS verification. GitLab versions may omit
`token_present`; `verification_token_present: null` remains unknown. Configuration is
not evidence that an event arrived or that a job ran. `provider_inspected: false` means
hook presence is unknown; an empty `hooks` array in that state proves nothing.

After applying, trigger an authorized real pipeline and verify retained demand for
that project, scheduling, and a running job. `last_demand_received_at` is historical,
not proof of current delivery. Do not cancel productive jobs just to generate events.
After a timeout, inspect first: an external GitLab write may have completed even if
RealHW could not finish its database transaction. The retained audit intent records
that uncertainty; rerunning reconciliation uses the same exact callback identity.

Developers: run API provider/receiver tests, isolated PostgreSQL scope/audit tests,
CLI contract tests, typeshare, and the docs build. Do not validate against production
by creating arbitrary hooks or writing credentials to disk.
