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
- GitLab → Preferences (or Admin → Applications on self-managed) → Applications → Add new application.
- Name: LingerCut local.
- Redirect URI:
http://localhost:4000/api/gitlab/callback - Confidential: yes.
- 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.
- 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
- On
/console, Sign in with GitLab. - LingerCut lists this app’s grant (real OAuth access token).
- Cut calls GitLab
POST /oauth/revoke. - Probe presents the old token to
GET /user. - 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)
- On
/console, Connect group inventory (requestsapi). - You must be Maintainer or Owner.
- Pick a group → Load group leftovers.
- 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
- 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
| Leftover | Live cut | Proof |
|---|---|---|
| LingerCut OAuth grant | Yes | GET /user (+ refresh if issued) |
| Personal / group / project access tokens | Yes | Absence re-list |
| Group / project deploy tokens | Yes | Absence re-list |
| CI job tokens / runner authentication tokens | No — demo rows only, labeled illustration | GitLab 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.