Chapter 02Lesson 02~175 minutes

Accounts, Two-Factor Authentication, SSH Keys, Access Tokens, Service Accounts, and Credentials: Guided Hands-On Workflow and Core Operations

Create a disposable SSH identity, verify GitLab host and project access, authenticate glab safely, exercise a minimal read-only API credential, and prove cleanup.

Hands-onSSHglabOAuthREST APICleanup

Learning objectives

  • Inspect account, Git remote, and glab authentication state without revealing secret material.
  • Generate a dedicated SSH keypair, register only its public key, verify the server host fingerprint, and test repository authorization.
  • Authenticate glab through a current supported OAuth flow and verify the selected GitLab host/context.
  • Use a temporary minimally scoped token for one read-only API call without placing the token in command history or source.
  • Revoke/remove every temporary credential and independently verify cleanup.

1. Preflight: use a disposable identity surface, not production credentials

Mandatory path: GitLab.com Free, the disposable project from Chapter 01 (or a fresh synthetic project), one dedicated SSH keypair, GitLab CLI, and a short-lived read-only personal token only for the scoped API exercise. Premium/Ultimate, Dedicated, Self-Managed admin rights, custom runners, cloud, and Kubernetes are not required.
  • Never reuse an employer SSH key or a production automation token for this lab.
  • Do not paste recovery codes, private keys, PAT values, browser cookies, or OAuth refresh tokens into source files, screenshots, chat, or shell command arguments.
  • Before creating a key/token, record its purpose, intended scope, expected lifetime, and cleanup action.
  • If your account is managed by an organization, do not weaken SSO or 2FA policy for the lab.

2. Inspect account and CLI state without exposing secrets

In GitLab, review the current account security pages for password/authentication methods, SSH keys, personal access tokens, and authorized applications. Record only metadata such as method type, key title/fingerprint, token name/scopes/expiry, and application name. Never copy the secret values.

# Local/CLI state: safe metadata only
git config --get user.name
git config --get user.email
git remote -v
glab auth status --hostname gitlab.com

Git commit author metadata is not an authentication credential. A commit can carry any configured name/email; GitLab access is decided by the transport/session/token identity and authorization policy.

3. Verify 2FA and recovery readiness safely

If 2FA is already enabled, confirm you still control at least one enrolled method and that recovery material is stored in an appropriate protected location. Do not reveal or regenerate codes merely to produce evidence. If 2FA is not enabled and this is your own disposable/personal account, follow the current GitLab setup flow only if you can securely retain recovery information.

Passkeys can reduce phishing risk when used correctly, but they do not remove the need to understand recovery. Organization-managed SSO can also change which sign-in methods are permitted. Record the method and policy, not the secret or biometric data.

4. Create a dedicated SSH keypair

Create a separate Ed25519 key so cleanup cannot accidentally remove your normal Git key. A passphrase is recommended when the key will live on a workstation.

# Bash, Git Bash, macOS, Linux, or Windows OpenSSH
ssh-keygen -t ed25519 -C "gitlab-ch02-disposable" \
  -f ~/.ssh/id_ed25519_gitlab_ch02

# Inspect fingerprints; this does not reveal the private key.
ssh-keygen -lf ~/.ssh/id_ed25519_gitlab_ch02.pub

Open the .pub file and register only that public key in your GitLab SSH key settings with a clear lab title and an expiry if the current UI supports your intended lifecycle. The file without .pub is the private key and must never be uploaded.

Do not use cat ~/.ssh/id_ed25519_gitlab_ch02 in a recorded terminal. There is no learning value in displaying private key material.

5. Verify the GitLab SSH host before trusting it

Before accepting a first-connection host key, compare the fingerprint shown by SSH with GitLab's currently published GitLab.com SSH host fingerprints. For a Self-Managed/Dedicated instance, use the instance-specific fingerprint source supplied by the operator.

# Force this test to use the dedicated lab identity.
ssh -o IdentitiesOnly=yes \
    -i ~/.ssh/id_ed25519_gitlab_ch02 \
    -T git@gitlab.com

Expected successful authentication identifies your GitLab username and explains that GitLab does not provide shell access. A success here proves the key maps to a GitLab account on this host. It does not prove push rights to the lab project.

6. Connect SSH authentication to one disposable project

Use the project's SSH clone URL and the dedicated identity. To avoid changing your normal SSH configuration, you can use GIT_SSH_COMMAND for a single read-only operation:

export GIT_SSH_COMMAND='ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_gitlab_ch02'
git ls-remote git@gitlab.com:YOUR_NAMESPACE/credential-hygiene-lab.git
unset GIT_SSH_COMMAND

Compare the returned default-branch SHA with the GitLab project page. This verifies both authentication and repository authorization without modifying a ref.

7. Authenticate glab with the current supported flow

For interactive GitLab.com use, current GitLab CLI documentation supports OAuth browser or device flows. OAuth avoids asking you to manually copy a reusable PAT into the command line.

# Browser-capable workstation
glab auth login --hostname gitlab.com --web --git-protocol ssh

# Headless environment: authorize using the one-time device flow
glab auth login --hostname gitlab.com --device

# Verify metadata without displaying token material
glab auth status --hostname gitlab.com
glab repo view -R YOUR_NAMESPACE/credential-hygiene-lab -F json

On Self-Managed/Dedicated, OAuth setup can require an application/client configuration and version support; PAT authentication remains another supported path. Verify the target instance documentation. Never add token-display flags to a recorded status command.

8. Perform a minimally scoped read-only API call

The mandatory API concept can be learned with a temporary PAT on GitLab Free. Create a token named ch02-readonly-lab, choose the shortest practical expiry, and grant only a read scope needed for the chosen request. The token value is shown once: place it directly into a secure input mechanism, not into a script or remote URL.

For a simple profile read, use a token with read_user. In Bash, prompt without echoing the value:

read -rsp "Temporary GitLab token: " GITLAB_TOKEN; echo
curl --silent --show-error --fail-with-body \
  --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
  "https://gitlab.com/api/v4/user" \
  | python -m json.tool
unset GITLAB_TOKEN

PowerShell can avoid command-history exposure by using a secure prompt, converting only inside the current process for the HTTP request, and clearing the variable afterward:

$secure = Read-Host "Temporary GitLab token" -AsSecureString
$token = [System.Net.NetworkCredential]::new("", $secure).Password
Invoke-RestMethod -Uri "https://gitlab.com/api/v4/user" `
  -Headers @{"PRIVATE-TOKEN" = $token}
$token = $null
Remove-Variable secure -ErrorAction SilentlyContinue

Expected output is your authenticated profile metadata. Do not save the complete response if it contains personal fields you would not publish.

9. Revoke temporary API credentials and remove the SSH key

Return to the token list and revoke ch02-readonly-lab. Then repeat the API request only if you can do so without recovering the old value; the important verification is that the token is listed revoked/inactive or no longer usable. Remove the dedicated SSH public key from GitLab and test that the dedicated identity no longer authenticates.

ssh -o IdentitiesOnly=yes \
    -i ~/.ssh/id_ed25519_gitlab_ch02 \
    -T git@gitlab.com
# After GitLab-side removal this dedicated identity should no longer authenticate.

Only after hosted removal is verified should you delete the local disposable keypair. Do not delete your default keys by pattern.

10. Read-only tour of credentials you should not create just to learn them

Feature Why no creation is required here What to inspect
Project/group access tokens GitLab.com creation is currently tier-dependent. Official docs: bot identity, role, scopes, expiry, resource boundary.
Service accounts Useful for automation but unnecessary for a beginner credential lab. Account cannot use normal UI sign-in; membership still grants authorization; quotas/creation roles vary.
Impersonation tokens Administrator-only and high impact. Self-Managed/Dedicated admin use, auditability, scope, expiry.
CI job token Chapter 10+ will execute pipelines. Job lifetime, endpoint limitations, target allowlist, triggering-user permissions.

11. Challenge — choose the credential before choosing the command

For each scenario, choose a credential class and justify why it is narrower than the alternatives: a human cloning over SSH; a workstation running glab; a CI job reading an allowed GitLab resource; an external deployment host pulling a package; a long-running integration independent of employee turnover. Do not create the credentials. Your answer must name identity, resource, protocol, lifetime, and revocation owner.

Knowledge check

Why does the SSH lab use a dedicated filename instead of ~/.ssh/id_ed25519?

What does ssh -T prove that git ls-remote additionally tests?

Why is OAuth a good default for interactive glab on GitLab.com?

After revoking a PAT, is deleting it from a shell script enough verification?

Summary

You inspected authentication state without disclosing secrets, created and removed a dedicated SSH key, verified the GitLab server identity, separated account authentication from repository authorization, authenticated glab with a supported flow, made one minimally scoped read-only API request, and revoked temporary credentials. The workflow deliberately proves state before and after every credential mutation.

Next lesson

Choose the right credential for the workload

Lesson 3 compares SSH versus HTTPS and the major GitLab token/service-identity choices using production tradeoffs rather than convenience alone.

Official references

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.