Operator setup · Residual Trust Assurance

GitLab connector setup

Kill receipt is VALID only after cut then adversarial replay of the old grant fails. Vendor revoked=true is not ground truth. Never put secrets in git.

  • GITLAB_CLIENT_ID
  • GITLAB_CLIENT_SECRET
  • GITLAB_REDIRECT_URI
  • GITLAB_BASE_URL

Local: set them in .env.local and restart npm run dev. Production: Vercel → Project → Settings → Environment Variables (Production), then redeploy. See deploy notes.

GitLab connector setup (local)

Required before live GitLab Cut works. Never commit secrets. Same kill-receipt bar as GitHub: cut out of band, then replay or re-list — VALID only on bounce.

GitHub in this app is live OAuth to github.com (no GHES base URL). GitLab is live OAuth/API to gitlab.com, with optional self-managed GITLAB_BASE_URL.

1. Create a GitLab OAuth application

  1. GitLab → Preferences (or Admin → Applications on self-managed) → ApplicationsAdd new application.
  2. Name: LingerCut local.
  3. Redirect URI: http://localhost:4000/api/gitlab/callback
  4. Confidential: yes.
  5. Scopes (least privilege):

- Self-grant cut: read_user (+ openid if offered). LingerCut revokes as the OAuth app (POST /oauth/revoke), then replays GET /user.

- Group leftover inventory: also enable api. GitLab has no finer scope for listing/deleting group and project access tokens or deploy tokens. You must be Maintainer/Owner on the group.

  1. Save. Copy Application ID and Secret.

Do not enable every scope. LingerCut never clones, pushes, or triggers a pipeline as proof.

2. Local env

In the repo root create or edit .env.local:

GITLAB_CLIENT_ID=paste-application-id
GITLAB_CLIENT_SECRET=paste-secret
GITLAB_REDIRECT_URI=http://localhost:4000/api/gitlab/callback
# Optional self-managed origin (no trailing slash). Default: https://gitlab.com
# GITLAB_BASE_URL=https://gitlab.example.internal

Restart npm run dev.

3. Self-grant Cut

  1. On /console, Sign in with GitLab.
  2. LingerCut lists this app’s grant (real OAuth access token).
  3. Cut calls GitLab POST /oauth/revoke.
  4. Probe presents the old token to GET /user.
  5. Kill receipt is VALID only if that call fails (and any refresh-token replay also fails).

GitLab returning success on revoke is not a VALID receipt.

4. Group leftover inventory (PATs, access tokens, deploy tokens)

  1. On /console, Connect group inventory (requests api).
  2. You must be Maintainer or Owner.
  3. Pick a group → Load group leftovers.
  4. LingerCut lists (absence re-list after delete — secrets are never returned by GitLab):

- Personal access tokens of the signed-in user (GET /personal_access_tokens)

- Group access tokens (GET /groups/{id}/access_tokens)

- Group deploy tokens (GET /groups/{id}/deploy_tokens)

- Project access tokens and project deploy tokens on up to 15 recently active projects in that group

  1. Cut deletes the credential, then re-lists. Receipt valid only if it is gone.

Accounts with no groups show an empty group section — expected.

5. What is live vs illustration

LeftoverLive cutProof
LingerCut OAuth grantYesGET /user (+ refresh if issued)
Personal / group / project access tokensYesAbsence re-list
Group / project deploy tokensYesAbsence re-list
CI job tokens / runner authentication tokensNo — demo rows only, labeled illustrationGitLab does not hand LingerCut those secrets for a bounce

Do not claim a live job-token or runner-token kill you cannot perform.

6. Public deploy

Add callback https://YOUR_DOMAIN/api/gitlab/callback on the OAuth application and set GITLAB_REDIRECT_URI + NEXT_PUBLIC_SITE_URL on the host. See docs/DEPLOY.md.