Open-Source Wikis

/

GitLab

/

API

/

Internal API

gitlab-org/gitlab

Internal API

The endpoints under /api/v4/internal/ exist so other GitLab services can talk back to Rails. They are not part of the public API.

Callers

  • GitLab Shell (SSH entry point) → /api/v4/internal/allowed, /lfs_authenticate, etc.
  • Workhorse/authorize endpoints and "preauthorize" handshakes for uploads / git-over-HTTP.
  • KAS/api/v4/internal/kubernetes/*.
  • Pages/api/v4/internal/pages/*.
  • GitLab Zoekt indexer/api/v4/internal/search/zoekt/*.
  • GitLab Elasticsearch indexer/api/v4/internal/elastic/*.
  • Geo secondaries/api/v4/geo/*.
  • Gitaly hooks/api/v4/internal/post_receive, /internal/pre_receive, etc.
  • Bulk imports source/api/v4/internal/bulk_imports/*.
  • Cloud Connector / AI Gateway/api/v4/internal/ai/....

Source

lib/api/internal/
├── base.rb                    # /allowed, /authorized_keys, /lfs_authenticate, /post_receive
├── kubernetes.rb              # KAS callbacks
├── pages.rb                   # Pages metadata
├── workhorse.rb               # Workhorse preauth
├── shell.rb                   # GitLab Shell helpers
├── observability.rb
├── bulk_imports/
├── search/zoekt/
├── elastic/                   # EE
└── ...
ee/lib/api/internal/           # Geo and EE-only endpoints

Authentication

Internal endpoints use shared-secret JWT or an API token. Notable schemes:

  • GitLab Shell secret (/etc/gitlab/gitlab-shell-secret): a long-lived shared secret for SSH callbacks.
  • Workhorse secret (/etc/gitlab/.gitlab_workhorse_secret): a shared HMAC for the X-Workhorse-Token header.
  • KAS JWT: per-agent token stored in Clusters::AgentToken.
  • Gitaly hook token: Gitlab::Shell::Hook shared secret.

The guard API::Helpers::InternalHelpers validates each request.

Examples

/api/v4/internal/allowed (called by Shell on every SSH push/pull)

Inputs: action (git-receive-pack etc.), key id or user id, project, ref, oldrev/newrev. Outputs: GL_ID, GL_USERNAME, GL_REPOSITORY, GL_PROJECT_PATH, gitaly addr+token, "status: true/false" with reason.

This call is the trust boundary that decides whether a git push proceeds.

/api/v4/internal/post_receive

Called by Gitaly's post-receive hook. Triggers downstream pipelines, hooks, and emits the "push" domain event.

/api/v4/internal/kubernetes/agent_info

Called by KAS to validate an agent token and return agent metadata.

/api/v4/internal/lfs_authenticate

Called by Shell when a user pushes/pulls LFS over SSH.

Why a separate API?

  • Different auth model — shared secret instead of per-user PATs.
  • Different rate-limit profile — high-volume, machine-to-machine.
  • Allows internal contracts to evolve quickly without breaking external clients.

Where to make changes

  • New internal endpoint: add to lib/api/internal/<area>.rb and mount in lib/api/api.rb.
  • New auth scheme: extend API::Helpers::InternalHelpers and document the shared secret.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Internal API – GitLab wiki | Factory