Nexus Service Accounts¶
All Nexus CI/CD authentication is managed through Vault. Credentials are never stored as GitLab CI/CD variables or in source code.
Account Overview¶
Three service accounts cover all automated Nexus operations:
| Account | Vault Path | Permissions | Used By |
|---|---|---|---|
svc-orchestrator |
secret/nexus/svc-orchestrator |
Docker + RPM + Raw + PyPI (read/write) | Platform CI/CD builds, deployments |
svc-executor |
secret/nexus/svc-executor |
RPM + Raw (read/write) | Executor CLI CI/CD builds |
svc-deployer |
secret/nexus/svc-deployer |
Docker pull only (read) | Kubernetes deployments, EC2 deployments |
When to Use Each Account¶
svc-orchestrator— Default for all platform services (server,ui,iam-api,notification-api, etc.). Handles Docker push on build, Docker pull on deploy, and PyPI publish forcwiq-common.svc-executor— Exclusive to theexecutorproject. Has write access only to RPM and raw artifact repositories. Cannot push Docker images.svc-deployer— Pull-only. Used by Kubernetes pods and EC2 deployment scripts that need to pull images from Nexus without build privileges.
Do not create new service accounts for individual services
All platform services share svc-orchestrator. Only create a new account if you genuinely need a different permission scope — for example, a service that should only be able to pull, not push. Coordinate with the infrastructure team to add the account to Vault and Nexus.
Authentication Flow in CI/CD¶
Nexus credentials are never injected as static GitLab CI/CD variables. Every pipeline fetches them at runtime from Vault using GitLab's JWT token:
sequenceDiagram
participant Job as CI/CD Job
participant Vault as HashiCorp Vault
participant Nexus as Nexus Registry
Job->>Vault: POST /v1/auth/jwt/login<br/>(CI_JOB_JWT_V2 token, role=nexus-ci)
Vault-->>Job: Vault client token
Job->>Vault: GET /v1/secret/nexus/svc-orchestrator<br/>(with Vault token)
Vault-->>Job: { username, password }
Job->>Nexus: docker login nexus.shared.cwiq.io:8443<br/>(username + password)
Job->>Nexus: docker push orchestrator-server:main-abc123
The shared CI templates in .gitlab-ci-common.yml implement this flow. Individual project pipelines do not need to replicate it — they inherit it by extending the template jobs.
See Vault JWT Auth for the complete authentication pattern, Vault role configuration, and how to add Vault access for a new service.
Human Access (Web UI)¶
The Nexus Web UI (nexus.shared.cwiq.io) uses Authentik SSO for human access. Log in with your Authentik credentials — the same ones you use for GitLab, Vault, and Grafana.
Human accounts can:
- Browse repositories and artifacts
- Download artifacts manually
- View storage usage and repository metadata
Human accounts cannot push artifacts. All artifact publishing is done by CI/CD service accounts.
Adding a New Service That Needs Nexus Access¶
For a new platform service that needs to push Docker images:
- The service uses the existing
svc-orchestratoraccount — no new account needed - Include the standard CI templates in the service's
.gitlab-ci.yml(see CI/CD Pipeline Overview) - The template's
.build-pushjob handles Docker login and push automatically
For a new service that needs only pull access (e.g., a deployment script):
- Use the
svc-deployeraccount - Retrieve credentials from
secret/nexus/svc-deployerin Vault - Run
docker login nexus.shared.cwiq.io:8444before pulling
For a new service that needs a distinct permission scope:
- Contact the infrastructure team to create the account in Nexus
- The infrastructure team adds the credentials to Vault at
secret/nexus/svc-{name} - Update the Vault JWT role policy to grant the new service access to that path
Vault Secret Structure¶
Each service account secret in Vault contains:
Fetching in a shell script:
# Authenticate to Vault (CI/CD — JWT flow)
VAULT_TOKEN=$(curl -s \
--request POST \
--data "{\"jwt\": \"${CI_JOB_JWT_V2}\", \"role\": \"nexus-ci\"}" \
"${VAULT_ADDR}/v1/auth/jwt/login" | jq -r '.auth.client_token')
# Read credentials
NEXUS_USER=$(curl -s \
--header "X-Vault-Token: ${VAULT_TOKEN}" \
"${VAULT_ADDR}/v1/secret/nexus/svc-orchestrator" | jq -r '.data.username')
NEXUS_PASSWORD=$(curl -s \
--header "X-Vault-Token: ${VAULT_TOKEN}" \
"${VAULT_ADDR}/v1/secret/nexus/svc-orchestrator" | jq -r '.data.password')
The shared CI template abstracts this into a reusable before-script block. Individual jobs do not call these endpoints directly.
Related Documentation¶
- Nexus Overview — Port architecture and repository types
- Docker Registry — How service accounts are used during image push and pull
- Vault JWT Auth — Complete Vault authentication pattern for CI/CD
- RPM & Raw Artifacts —
svc-executoraccount usage for RPM uploads