The service uses two configuration sources:
- YAML config file (
config_v2.pymodels) — non-secret service configuration: project definitions, integrations, dispatch backend, prompts, polling settings - Environment variables (
config/package /Settings) — secrets and runtime overrides: tokens, connection strings, auth credentials
Secrets never go in the YAML file. The YAML file path is set via the CONFIG_FILE env var (default: config.yaml).
The YAML config file uses version: 2 and is validated by Pydantic models in config_v2.py. Generate the JSON Schema with mapping-helper schema. See config.example.yaml for a documented example.
version: 2 # Required — must be 2
gitlab:
url: https://gitlab.example.com # Required — GitLab instance URL
dispatch:
backend: local # local | k8s | aca (default: local)
copilot:
model: gpt-4 # Default model for Copilot sessions
plugins: [] # Copilot CLI plugins
marketplaces: [] # Custom marketplace URLs (audit-logged at startup)
server:
log_level: info
clone_dir: null # Base directory for repo clones
shutdown_timeout: 30 # Graceful shutdown timeout (seconds)
webhook_ip_allowlist: [] # CIDR ranges allowed to send webhooks (empty = all)
trusted_proxies: [] # Reverse proxy CIDRs for X-Forwarded-For
prompts: # Prompt overrides and suffixes
system: null
review_suffix: null
# ... (system_suffix, review, coding, coding_suffix, discussion, discussion_suffix)
defaults: # Applied to every project unless overridden
target_branch: main
credential_ref: default
resolution_behavior: suggest # auto-resolve | suggest | off
webhook: true
poll:
enabled: false
interval: 30
lookback_minutes: 60
review_on_push: true
projects: # GitLab project definitions
- repo: group/my-project
credential_ref: default # Override credential alias
target_branch: main # Override target branch
resolution_behavior: suggest
webhook: true
poll:
enabled: false
copilot: # Per-project Copilot overrides
model: gpt-4o
integrations: # References to named integrations
- my-jira
integrations: # Named integration configurations
- name: my-jira
type: jira
project_key: PROJ
trigger_status: "AI Ready"
in_progress_status: "In Progress"
in_review_status: "In Review"mapping-helper validate-v2 config.yaml— full Pydantic validationmapping-helper schema > config.schema.json— generate JSON Schema- Cross-field validators: integration refs must point to defined integrations, no duplicate repos
| Environment | Config Path |
|---|---|
| Local | ./config.yaml (default) |
| K8s | Helm ConfigMap → /etc/copilot-agent/config.yaml |
| ACA | Terraform-rendered secret/volume |
Every environment variable in the config/ package, grouped by category.
- Type:
str - Required: ✅ Yes
- Description: GitLab instance URL (e.g.,
https://gitlab.example.com) - Validation: Must be valid URL
- Type:
str - Required: ✅ Yes
- Description: GitLab API token with
apiscope. Recommended: Use project access tokens scoped to specific projects for least-privilege access, rather than personal access tokens. - Security: Read/write access to all allowed projects, webhook processing
- Validation: Non-empty string
- Type:
str | None - Required: ❌ No (required for webhook mode, optional for polling-only)
- Default:
None - Description: Secret for validating webhook payloads via HMAC (X-Gitlab-Token header). When not set, the
/webhookendpoint returns 403. - Security: Must match GitLab webhook configuration when using webhooks
At least one of these must be set:
- Type:
str | None - Required:
⚠️ If not using BYOK - Default:
None - Description: GitHub token for Copilot auth. Accepts PATs with
copilotscope, fine-grained PATs, or GitHub App installation tokens. Recommended: Use GitHub App tokens for automated rotation and audit trails. - Security: Authorizes Copilot API access
- Validation: Cross-checked with
COPILOT_PROVIDER_TYPEin_check_auth()
- Type:
str | None - Required:
⚠️ If not using GitHub Copilot - Default:
None - Options:
"azure","openai", orNonefor Copilot - Description: BYOK provider type (Bring Your Own Key)
- Type:
str | None - Required: ❌ No (required if
COPILOT_PROVIDER_TYPEis set) - Default:
None - Description: BYOK provider base URL (e.g.,
https://api.openai.com/v1)
- Type:
str | None - Required: ❌ No (required if
COPILOT_PROVIDER_TYPEis set) - Default:
None - Description: BYOK provider API key
- Security: Stored in Kubernetes Secret, passed as env var
- Type:
str - Required: ❌ No
- Default:
"gpt-4" - Description: Model to use for reviews and coding tasks
- Type:
str - Required: ❌ No
- Default:
"0.0.0.0" - Description: Server bind host
- Type:
int - Required: ❌ No
- Default:
8000 - Description: Server bind port
- Type:
str - Required: ❌ No
- Default:
"info" - Options:
"debug","info","warning","error" - Description: Log level for structlog
- Type:
str | None - Required: ❌ No
- Default:
None - Deprecated:
⚠️ Agent identity is now auto-discovered viaGET /userusing the existingGITLAB_TOKEN. TheCredentialRegistrylazily resolves and caches the agent'sAgentIdentity(immutableuser_id+username) per credential on first use. No new env vars are needed. - Description: Previously used for loop prevention (skips self-authored notes). Retained for backward compatibility but no longer required.
- Example:
"copilot-agent"
- Type:
str | None - Required: ❌ No
- Default:
None(uses system temp dir) - Description: Base directory for repo clones (useful for persistent volumes)
- Type:
bool - Required: ❌ No
- Default:
false - Description: When
false(default), coding tasks create Draft MRs that require manual un-drafting before merge. Whentrue, MRs are created as ready-to-merge.
- Type:
str | None - Required: ❌ No
- Default:
None - Description: Separate authentication token for the
/config/reloadendpoint. When set, the endpoint requires anX-Admin-Tokenheader matching this value. When not set, falls back toX-Gitlab-Token(webhook secret) for backward compatibility. - Security: Generate with
openssl rand -hex 32. Use a unique value distinct fromGITLAB_WEBHOOK_SECRET— separating these tokens limits blast radius if either is leaked.
- Type:
str - Required: ❌ No
- Default:
"file-based" - Options:
"inline","file-based" - Description: Controls how MR context (diff, description, discussions) is passed to the LLM.
"file-based"(default) writes context to files and instructs the agent to read them via filesystem access +git diff, producing shorter prompts."inline"embeds all context directly in the prompt for backward compatibility.
- Type:
Literal["local", "kubernetes", "container_apps"] - Required: ❌ No
- Default:
"local" - Options:
"local"(in-process),"kubernetes"(K8s Jobs),"container_apps"(Azure Container Apps Jobs) - Description: Task executor backend
- Type:
str | list[str] - Required: ❌ No
- Default:
[] - Description: Copilot CLI plugins to install at runtime. Accepts comma-separated string (
"plugin-a, plugin-b") or JSON array ('["plugin-a", "plugin-b"]'). Each spec can be a marketplace plugin name (name@marketplace), GitHub repo (owner/repo), Git URL, or local path (./my-plugin). - Example:
"my-jira-plugin@awesome-copilot, ./local-plugin"
- Type:
str | list[str] - Required: ❌ No
- Default:
[] - Description: Custom plugin marketplace URLs or paths to register before plugin installation. Accepts comma-separated string or JSON array. Each entry can be a GitHub repo (
owner/repo), Git URL, or local filesystem path. - Example:
"my-org/our-plugins, /opt/local-marketplace"
All remote executors (kubernetes, container_apps) use Azure Storage Queue + Blob for dispatch (Claim Check pattern). KEDA ScaledJob watches the queue and triggers Job pods automatically.
- Type:
Literal["azure_storage"] - Required: ❌ No
- Default:
"azure_storage" - Description: Dispatch backend for task queue and result storage. Tasks are dispatched via Azure Storage Queue (Claim Check: params blob + queue message). Results stored as blobs.
- Type:
str | None - Required:
⚠️ Required for K8s/Azurite deployments (unless URL-based auth is used) - Default:
None - Description: Azure Storage connection string. Used with Azurite (local K8s) or real Azure Storage. Overrides URL-based auth when set.
- Example:
"DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=...;BlobEndpoint=http://azurite:10000/devstoreaccount1;QueueEndpoint=http://azurite:10001/devstoreaccount1"
- Type:
str | None - Required:
⚠️ Required for ACA (managed identity auth) unlessAZURE_STORAGE_CONNECTION_STRINGis set - Default:
None - Description: Azure Blob Storage account URL for
DefaultAzureCredentialauth - Example:
"https://mystorageaccount.blob.core.windows.net"
- Type:
str | None - Required:
⚠️ Required for ACA (managed identity auth) unlessAZURE_STORAGE_CONNECTION_STRINGis set - Default:
None - Description: Azure Queue Storage endpoint URL for
DefaultAzureCredentialauth - Example:
"https://mystorageaccount.queue.core.windows.net"
- Type:
str - Required: ❌ No
- Default:
"task-queue" - Description: Azure Storage Queue name for task dispatch
- Type:
str - Required: ❌ No
- Default:
"task-data" - Description: Azure Blob container name for params and result blobs
Only used when TASK_EXECUTOR=kubernetes.
- Type:
str - Required: ❌ No
- Default:
"default" - Description: Kubernetes namespace for Jobs
- Type:
str - Required:
⚠️ Yes ifTASK_EXECUTOR=kubernetes - Default:
"" - Description: Docker image for Job pods (must include agent code)
- Example:
"ghcr.io/peteroden/gitlab-copilot-agent:latest"
- Type:
str - Required: ❌ No
- Default:
"1" - Description: CPU limit for Job pods (K8s resource format)
- Example:
"2","500m"
- Type:
str - Required: ❌ No
- Default:
"1Gi" - Description: Memory limit for Job pods (K8s resource format)
- Example:
"2Gi","512Mi"
- Type:
int - Required: ❌ No
- Default:
600 - Description: Job timeout in seconds (10 minutes)
- Type:
str - Required: ❌ No
- Default:
""(empty — no host aliases) - Description: JSON-encoded array of hostAliases for Job pods. Each entry must have
ipandhostnameskeys. Useful for environments with custom DNS (air-gapped, k3d dev). - Format:
[{"ip": "10.0.0.1", "hostnames": ["host.local", "api.local"]}] - Validation: JSON structure validated at startup (must be array of objects with
ipandhostnames) - Helm Value: Auto-generated from
hostAliasesvalue (serialized to JSON)
- Type:
str | None - Required: ❌ No (but recommended for K8s deployments)
- Default:
None - Description: K8s Secret name for mounting Job pod credentials via
secretKeyRef. When set, sensitive env vars (GITLAB_TOKEN,GITHUB_TOKEN,COPILOT_PROVIDER_API_KEY,GITLAB_WEBHOOK_SECRET) are referenced from this Secret instead of passed as plaintext. A startup warning is logged when running the K8s executor without this configured. - Helm Value: Auto-set to the chart's Secret name
- Type:
str | None - Required: ❌ No
- Default:
None - Description: K8s ConfigMap name for mounting Job pod non-sensitive config via
configMapKeyRef. When set, config values (DISPATCH_BACKEND,COPILOT_MODEL,COPILOT_PROVIDER_TYPE,COPILOT_PROVIDER_BASE_URL,TASK_QUEUE_NAME,TASK_BLOB_CONTAINER) are referenced from this ConfigMap. - Helm Value: Auto-set to the chart's ConfigMap name
- Type:
str - Required: ❌ No
- Default:
""(empty) - Description: Helm release instance label added to Job pods as
app.kubernetes.io/instance. Used by NetworkPolicies to scope access to pods within the same Helm release. - Helm Value: Auto-set to
{{ .Release.Name }}
Only used when TASK_EXECUTOR=container_apps.
- Type:
str | None - Required:
⚠️ Yes ifTASK_EXECUTOR=container_apps - Description: Azure subscription ID containing the Container Apps Job
- Type:
str | None - Required:
⚠️ Yes ifTASK_EXECUTOR=container_apps - Description: Resource group containing the Container Apps Job
- Type:
str | None - Required:
⚠️ Yes ifTASK_EXECUTOR=container_apps - Description: Name of the Container Apps Job resource to trigger
- Type:
int - Required: ❌ No
- Default:
600 - Description: Maximum execution time in seconds before timeout
Validation: If TASK_EXECUTOR=container_apps, all three ACA settings (ACA_SUBSCRIPTION_ID, ACA_RESOURCE_GROUP, ACA_JOB_NAME) must be set. A ValueError is raised at startup if any are missing.
- Type:
str | None - Required:
⚠️ Yes ifGITLAB_POLL=true - Default:
None - Description: Comma-separated GitLab project paths or IDs to scope webhook and poller
- Format:
"group/project1,group/project2,12345" - Validation: Each entry resolved to numeric ID at startup; required when
GITLAB_POLL=true
- Type:
bool - Required: ❌ No
- Default:
False - Description: Enable GitLab API polling for MR and note discovery (alternative to webhooks)
- Type:
int - Required: ❌ No
- Default:
30 - Description: Polling interval in seconds
- Type:
int - Required: ❌ No
- Default:
60 - Description: Minutes to look back on startup for recently created or updated MRs. The deduplication store prevents re-reviewing the same commit, so a generous lookback is safe.
- Type:
bool - Required: ❌ No
- Default:
True - Description: When
true(default), the agent re-reviews an MR each time a new commit is pushed. Whenfalse, each MR is reviewed only once regardless of subsequent commits. Useful for reducing noise when developers iterate frequently on an MR.
- Type:
str - Required: ❌ No
- Default:
"suggest" - Description: Controls how the agent handles its prior feedback that has been addressed by new commits or developer replies. Three modes:
auto-resolve: Resolves the thread via GitLab API with an acknowledgment reply (✅)suggest: Posts an acknowledgment reply but leaves the thread open for manual review (default)off: Takes no action on addressed feedback
- Per-project override: Yes, via
resolution_behaviorin mapping YAML bindings - Note: Partially addressed feedback is never auto-resolved regardless of this setting
All optional — service runs review-only without these.
- Type:
str | None - Required: ❌ No
- Default:
None - Description: Jira instance URL (e.g.,
https://company.atlassian.net)
- Type:
str | None - Required: ❌ No
- Default:
None - Description: Jira user email for basic auth
- Type:
str | None - Required: ❌ No
- Default:
None - Description: Jira API token or PAT
- Security: Stored in Kubernetes Secret
- Type:
str - Required: ❌ No
- Default:
"AI Ready" - Description: Jira status that triggers the agent
- Note: The demo provisioner (
scripts/demo_provision.py) auto-creates this status on the Jira board
- Type:
str - Required: ❌ No
- Default:
"In Progress" - Description: Status to transition to after agent picks up issue
- Type:
str - Required: ❌ No
- Default:
"In Review" - Description: Status to transition to after MR creation
- Type:
int - Required: ❌ No
- Default:
30 - Description: Poll interval in seconds
- Type:
str | None - Required: ❌ No
- Default:
None - Description: JSON string mapping Jira project keys to GitLab projects
- Format: See Jira Project Map Format below
Jira Activation Logic: All of JIRA_URL, JIRA_EMAIL, JIRA_API_TOKEN, and JIRA_PROJECT_MAP must be set. The Settings.jira property returns JiraSettings if all required fields are present, else None.
- Type:
str(not in Settings model, read directly bytelemetry/package) - Required: ❌ No
- Default: Unset (telemetry disabled)
- Description: OTLP gRPC endpoint for traces, metrics, and logs
- Example:
"http://otel-collector:4317" - Behavior:
- If unset,
init_telemetry()is a no-op — zero overhead - If set but collector is unreachable, the service starts normally and logs
otel_collector_unavailable. A background task probes the endpoint every 30s and logsotel_collector_connectedwhen the collector becomes available. - OTEL SDK retry messages are suppressed (routed through structlog at WARNING level only for persistent failures). No unstructured retry spam in the console.
- If unset,
- Type:
str(not in Settings model) - Required: ❌ No
- Default:
"0.1.0" - Description: Service version for OTEL resource attributes
- Type:
str(not in Settings model) - Required: ❌ No
- Default:
"" - Description: Deployment environment label (e.g., "production", "staging")
The project map uses a rendered JSON format for the JIRA_PROJECT_MAP env var. This is typically generated from a YAML source file using the mapping-helper CLI.
Create a mappings.yaml file:
defaults:
target_branch: main
credential_ref: default
trigger_status: "AI Ready" # optional — this is the default
in_progress_status: "In Progress"
in_review_status: "In Review"
bindings:
- jira_project: PROJ
repo: group/project
- jira_project: OPS
repo: platform/tools
target_branch: develop
credential_ref: platform_team
trigger_status: "Ready for Dev" # per-project override
in_review_status: "Code Review" # per-project overrideThe three Jira workflow statuses can be set at the defaults level (applied to every
binding) or overridden per binding:
| Field | Default | Description |
|---|---|---|
trigger_status |
"AI Ready" |
Status that causes the poller to pick up the issue |
in_progress_status |
"In Progress" |
Status the agent transitions to when it starts work |
in_review_status |
"In Review" |
Status the agent transitions to after creating an MR |
The global env vars JIRA_TRIGGER_STATUS, JIRA_IN_PROGRESS_STATUS, and
JIRA_IN_REVIEW_STATUS act as a fallback when no YAML mapping is used. When a
YAML mapping is present the per-binding (or per-defaults) values always take
precedence.
The resolution_behavior can be overridden per binding in the YAML mapping file:
defaults:
resolution_behavior: suggest # default for all projects
bindings:
- jira_project: PROJ
repo: group/service-a
resolution_behavior: auto-resolve # this team wants auto-resolution
- jira_project: OPS
repo: group/platform-tools
resolution_behavior: "off" # this team manages threads manuallyWhen a YAML mapping is present, the per-binding value takes precedence over the
RESOLUTION_BEHAVIOR env var.
Generate with mapping-helper render-json mappings.yaml:
{
"mappings": {
"PROJ": {
"repo": "group/project",
"target_branch": "main",
"credential_ref": "default"
},
"OPS": {
"repo": "platform/tools",
"target_branch": "develop",
"credential_ref": "platform_team"
}
}
}- Jira project key (e.g.,
"PROJ"): Top-level keys inmappings - repo (
str): GitLab repo path (e.g.,group/project) - target_branch (
str): Default MR target branch - credential_ref (
str): Credential alias —"default"usesGITLAB_TOKEN, named aliases useGITLAB_TOKEN__<ALIAS>(e.g.,credential_ref: platform_team→GITLAB_TOKEN__PLATFORM_TEAM)
# Validate YAML syntax and semantics
mapping-helper validate mappings.yaml
# Show human-readable summary
mapping-helper show mappings.yaml
# Render JSON for JIRA_PROJECT_MAP env var
mapping-helper render-json mappings.yamlSet additional GitLab tokens as env vars with the GITLAB_TOKEN__ prefix:
GITLAB_TOKEN=glpat-default-token # Used by credential_ref: default
GITLAB_TOKEN__PLATFORM_TEAM=glpat-other # Used by credential_ref: platform_teamAlias matching is case-insensitive. Startup fails fast if a binding references an unknown alias.
Create a project access token in GitLab (Settings → Access Tokens) with these settings:
Role: Developer (minimum). Guest and Reporter are insufficient — the agent needs Developer-level access to list merge requests, post comments, push code, and resolve threads.
Scopes:
| Scope | Required for |
|---|---|
api |
MR details, discussions, posting comments, resolving threads |
read_repository |
Git clone for code review and discussion context |
write_repository |
Git push for coding tasks (commit changes from @mention requests) |
When deploying to Azure Container Apps, three files need updating:
- GitHub Actions secret — create
GITLAB_TOKEN__<ALIAS>(double underscore) in repo settings (use environment-scoped secrets if the token is env-specific) deploy.yml— add the KV entry toTF_VAR_kv_bootstrap_secrets:The KV name uses hyphens (TF_VAR_kv_bootstrap_secrets: >- { ...existing entries..., "gitlab-token--<alias>": "${{ secrets.GITLAB_TOKEN__<ALIAS> }}" }
gitlab-token--<alias>). The ACA env var transform (upper+replace("-","_")) producesGITLAB_TOKEN__<ALIAS>.<env>.tfvars— setcredential_refin the project binding:{"repo":"group/project","target_branch":"main","credential_ref":"<alias>"}
The agent auto-discovers its identity per token via GET /user — no username configuration needed.
Update mappings at runtime without restart:
mapping-helper render-json updated-mappings.yaml | \
curl -X POST http://localhost:8000/config/reload \
-H 'Content-Type: application/json' \
-H 'X-Gitlab-Token: <webhook-secret>' \
-d @-The endpoint atomically swaps the registry and clears dedup state. New credentials (GITLAB_TOKEN__* env vars) require a container restart.
| Validator | Condition | Error |
|---|---|---|
_check_auth() |
Neither GITHUB_TOKEN nor COPILOT_PROVIDER_TYPE set |
"Either GITHUB_TOKEN or COPILOT_PROVIDER_TYPE must be set" |
_check_azure_storage() |
dispatch_backend='azure_storage' and no AZURE_STORAGE_CONNECTION_STRING and missing AZURE_STORAGE_ACCOUNT_URL or AZURE_STORAGE_QUEUE_URL |
"dispatch_backend='azure_storage' requires: ... (or set AZURE_STORAGE_CONNECTION_STRING)" |
_check_aca_resources() |
TASK_EXECUTOR=container_apps and missing ACA settings |
"Container Apps executor requires: ..." |
_check_auth() |
GITLAB_POLL=true and GITLAB_PROJECTS is empty |
"GITLAB_PROJECTS is required when GITLAB_POLL=true" |
GITLAB_URL=https://gitlab.example.com
GITLAB_TOKEN=glpat-xxxxx
GITLAB_WEBHOOK_SECRET=my-secret
GITHUB_TOKEN=ghp_xxxxxGITLAB_URL=https://gitlab.example.com
GITLAB_TOKEN=glpat-xxxxx
GITLAB_WEBHOOK_SECRET=my-secret
GITHUB_TOKEN=ghp_xxxxx
GITLAB_POLL=true
GITLAB_POLL_INTERVAL=60
GITLAB_PROJECTS="group/project1,group/project2"
AGENT_GITLAB_USERNAME=copilot-agentGITLAB_URL=https://gitlab.example.com
GITLAB_TOKEN=glpat-xxxxx
GITLAB_WEBHOOK_SECRET=my-secret
GITHUB_TOKEN=ghp_xxxxx
TASK_EXECUTOR=kubernetes
K8S_NAMESPACE=copilot-agent
K8S_JOB_IMAGE=ghcr.io/peteroden/gitlab-copilot-agent:v1.0.0
K8S_JOB_CPU_LIMIT=2
K8S_JOB_MEMORY_LIMIT=2Gi
K8S_JOB_TIMEOUT=900
DISPATCH_BACKEND=azure_storage
AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;... # Azurite
# Or for real Azure: AZURE_STORAGE_ACCOUNT_URL + AZURE_STORAGE_QUEUE_URL (managed identity)
GITLAB_POLL=true
GITLAB_POLL_INTERVAL=30
GITLAB_PROJECTS="group/infra,group/app"
AGENT_GITLAB_USERNAME=copilot-agent
JIRA_URL=https://company.atlassian.net
JIRA_EMAIL=bot@example.com
JIRA_API_TOKEN=xxxxx
JIRA_TRIGGER_STATUS="AI Ready"
JIRA_IN_PROGRESS_STATUS="In Progress"
JIRA_IN_REVIEW_STATUS="In Review"
JIRA_POLL_INTERVAL=30
JIRA_PROJECT_MAP='{"mappings":{"PROJ":{"repo":"group/project","target_branch":"main","credential_ref":"default"}}}'
RESOLUTION_BEHAVIOR=suggest
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317
SERVICE_VERSION=1.0.0
DEPLOYMENT_ENV=productionGITLAB_URL=https://gitlab.example.com
GITLAB_TOKEN=glpat-xxxxx
GITLAB_WEBHOOK_SECRET=my-secret
COPILOT_PROVIDER_TYPE=azure
COPILOT_PROVIDER_BASE_URL=https://my-resource.openai.azure.com
COPILOT_PROVIDER_API_KEY=xxxxx
COPILOT_MODEL=gpt-4All tokens/keys should be:
- Stored in Kubernetes Secrets (or External Secrets Operator for production)
- Mounted as environment variables (Helm chart handles this)
- Never committed to code
- Rotated regularly (quarterly recommended)
Rotation procedure: Update the token value in your K8s Secret (or secrets manager) and restart pods. All credentials are stateless env vars — no migration needed.
- GITLAB_TOKEN: Scope to specific projects if possible (use project access tokens)
- GITHUB_TOKEN: Minimal scope (
copilotonly) - JIRA_API_TOKEN: Read issue, transition, add comment (no admin)
- Azure Storage (Azurite): NetworkPolicies restrict access to agent and job pods only
- OTEL Collector: internal endpoint only
- Job pods: egress restricted to GitLab, Copilot API, Azure Storage, and DNS via NetworkPolicy
Helm values.yaml maps to env vars via configmap.yaml and secret.yaml:
| Helm Value | Env Var | Secret? |
|---|---|---|
gitlab.url |
GITLAB_URL |
❌ |
gitlab.token |
GITLAB_TOKEN |
✅ |
gitlab.webhookSecret |
GITLAB_WEBHOOK_SECRET |
✅ (optional for polling-only) |
github.token |
GITHUB_TOKEN |
✅ |
controller.copilotProviderType |
COPILOT_PROVIDER_TYPE |
❌ |
controller.copilotProviderBaseUrl |
COPILOT_PROVIDER_BASE_URL |
❌ |
controller.copilotProviderApiKey |
COPILOT_PROVIDER_API_KEY |
✅ |
controller.copilotPlugins |
COPILOT_PLUGINS |
❌ |
controller.copilotPluginMarketplaces |
COPILOT_PLUGIN_MARKETPLACES |
❌ |
controller.copilotModel |
COPILOT_MODEL |
❌ |
controller.taskExecutor |
TASK_EXECUTOR |
❌ |
controller.dispatchBackend |
DISPATCH_BACKEND |
❌ |
azurite.enabled |
AZURE_STORAGE_CONNECTION_STRING (auto-generated) |
✅ (connection string) |
| (auto) | K8S_SECRET_NAME |
❌ |
| (auto) | K8S_CONFIGMAP_NAME |
❌ |
| (auto) | K8S_JOB_INSTANCE_LABEL |
❌ |
telemetry.otlpEndpoint |
OTEL_EXPORTER_OTLP_ENDPOINT |
❌ |
telemetry.environment |
DEPLOYMENT_ENV |
❌ |
jira.url |
JIRA_URL |
❌ |
jira.email |
JIRA_EMAIL |
✅ |
jira.apiToken |
JIRA_API_TOKEN |
✅ |
jira.projectMap |
JIRA_PROJECT_MAP |
❌ |
jira.triggerStatus |
JIRA_TRIGGER_STATUS |
❌ |
jira.inProgressStatus |
JIRA_IN_PROGRESS_STATUS |
❌ |
jira.inReviewStatus |
JIRA_IN_REVIEW_STATUS |
❌ |
jira.pollInterval |
JIRA_POLL_INTERVAL |
❌ |
controller.resolutionBehavior |
RESOLUTION_BEHAVIOR |
❌ |
extraEnv |
(arbitrary key-value pairs) | ❌ |
hostAliases |
K8S_JOB_HOST_ALIASES (JSON for Job pods) |
❌ |
hostAliases |
Pod /etc/hosts entries (controller pod) |
❌ |
See helm/gitlab-copilot-agent/values.yaml for full reference.
These settings are used exclusively for E2E testing and must never be enabled in production.
- Type:
str - Required: ❌ No
- Default: unset (HTTP clone disabled)
- Description: When set to
true,1, oryes, allows git clone over HTTP instead of requiring HTTPS. Used by E2E tests with mock git servers. ⚠️ Security: Never enable in production — disables TLS verification for clone URLs.
- Type:
map - Default:
{} - Description: Arbitrary key-value pairs injected into the ConfigMap. Empty values are skipped. Used to pass test-only env vars like
ALLOW_HTTP_CLONEwithout adding them to the chart schema.
- Type:
list - Default:
[] - Description: Pod-level
/etc/hostsentries. Used in E2E tests to resolvehost.k3d.internalto the Docker host gateway IP so the agent pod can reach mock services running on the host.