Skip to main content

Configure a CodeGraph deployment

Configure secrets, network settings, model providers, and OpenViking in an installed CodeGraph instance, then verify service readiness.

Getting Started

The administrator sets secrets and environment values in .env and non-secret application settings in config.yaml. Use the files shipped with the installed CodeGraph version. After a change, restart the affected services and verify readiness using the steps below.

Configuration sources

Configuration sources
Source Purpose Customer deployment location
.env.example Version-bound list of supported environment variables Reference only; do not store real secrets in it
.env Secrets and deployment-specific environment values /opt/codegraph/.env
config.yaml Non-secret application behavior and ${VARIABLE} interpolation /opt/codegraph/config.yaml
projects.yaml Declared project configuration where the deployment profile uses it /opt/codegraph/projects.yaml

The environment variable reference lists all shipped server variables, sample values, and Docker Compose fallbacks.

Configure the deployment through .env and config.yaml. Store credentials in the protected .env or the customer secret store; keep them out of Git, command-line arguments, service files, and logs.

Required production values

Start from the .env.example shipped with the exact installed release. At minimum, set:

POSTGRES_PASSWORD=<secret-from-approved-store>
API_JWT_SECRET=<random-secret-at-least-64-characters>
API_ADMIN_PASSWORD=<unique-initial-admin-secret>
API_PROVIDER_SECRET_KEY=<independent-random-encryption-secret>
ENVIRONMENT=production

Also configure every required Eva integrity key and at least one approved model-provider credential listed by that release. Replace placeholders with environment-specific values and keep sample values in the documentation only.

Use a random value of at least 64 characters for API_JWT_SECRET. This is the recommended configuration size; the application rejects an empty secret and the shipped default value. Rotating it invalidates existing tokens, so coordinate the restart and user reauthentication. Treat the initial admin credential as a bootstrap secret and rotate it under the customer’s identity procedure.

In the standard Ubuntu installation, docker-compose.yml forwards API_PROVIDER_SECRET_KEY and CODEGRAPH_OUTBOUND_GIT_ORIGIN_ALLOWLIST to api and temporal-worker. The following connection-encryption and private-Git-origin steps apply to that profile. The standalone docker-compose.prod.yml does not forward these variables in this version. Use the standard profile to configure these two values.

API_PROVIDER_SECRET_KEY encrypts Git-provider tokens and webhook secrets stored through the UI or REST API. It is empty by default; production cannot store an inline connection token without it. Generate a separate random value, for example with python3 -c 'import secrets; print(secrets.token_urlsafe(48))', and store it in the protected .env. Generate it in a protected terminal without recording its output in logs or evidence. From /opt/codegraph, use Bash and the Compose files selected for this deployment to recreate the API and worker containers:

sudo docker compose up -d --no-deps --force-recreate api temporal-worker

Keep the key with the protected configuration backup: it decrypts tokens after database restoration. Preserve it during normal upgrades. Replacing it requires re-entering the previously stored connection tokens.

Network and browser origins

Set the externally reachable hosts and browser origins explicitly:

CORS_ALLOWED_ORIGINS=https://codegraph.customer.example
API_ALLOWED_HOSTS=codegraph.customer.example,api,codegraph-api

Do not use a wildcard origin with credentialed browser access. Terminate TLS according to the customer deployment design and expose only approved endpoints. For model, repository, telemetry and notification integrations, supply credentials and the approved network destinations for the selected service.

If an internal Git server resolves to a private address, the administrator can approve its exact HTTPS origin in the protected .env:

CODEGRAPH_OUTBOUND_GIT_ORIGIN_ALLOWLIST=https://git.internal.example

The default is empty: no private Git origins are exempted. Separate multiple origins with commas. List only trusted servers; IP ranges and wildcards are unsupported. Recreate api and temporal-worker after changing the value, then test connection creation in the UI or through POST /api/v1/integrations/repositories/provider-connections. The request schema is available at <API_BASE_URL>/api/docs. Provide a Git access token when creating the connection.

Non-secret application settings

Use config.yaml to select runtime capabilities, limits, providers, and ${VARIABLE} references. Check parameter names and types against the config.yaml shipped with the installed version. Preserve the other settings when changing a section.

Change individual project settings through the dashboard project page or API. The next section gives a complete API example for configuring the audit scope.

Project audit scope

In versions supporting metadata.audit.scope, configure each project separately. You need administrator permissions or the group’s editor role with access to the project. See RBAC for role and project assignment. This setting selects directories within that repository.

Project audit scope
Field Default Purpose
version 1 Format version; other values are rejected
include_paths ["."] Nonempty list of included paths relative to the project root
exclude_paths Standard exclusions below An explicit list replaces the standard exclusions
test_paths [] Test paths and patterns within the included scope

Standard exclusions are .git, .svn, .hg, node_modules, __pycache__, .venv, venv, vendor, third_party, build, dist, target, bin, obj, .idea, and .vscode. Version-control directories remain excluded even with an empty exclude_paths. Paths are case-sensitive. Patterns support *, ?, and **; absolute paths, .., and patterns containing !, {}, or [] are rejected. test_paths cannot expand the scope: include test directories and do not exclude them.

This example includes the entire project with standard exclusions and classifies tests as a test directory. Replace test_paths with your project’s paths. Save the code as configure-audit-scope.py on your workstation. Python 3 is required; no third-party packages are needed. Run python3 configure-audit-scope.py on Linux/macOS or py -3 configure-audit-scope.py on Windows. Obtain the API URL from your administrator, for example https://codegraph.customer.example. Swagger is available at <API_BASE_URL>/api/docs.

import getpass
import json
import urllib.request
from urllib.parse import urlsplit

base = input("API base URL: ").strip().rstrip("/")
parsed = urlsplit(base)
local_http = parsed.scheme == "http" and parsed.hostname in {"localhost", "127.0.0.1", "::1"}
if not parsed.hostname or parsed.username or parsed.password:
    raise ValueError("API URL must contain a host and no credentials")
if parsed.scheme != "https" and not local_http:
    raise ValueError("Use HTTPS; HTTP is allowed only for a local loopback API")
username = input("Username: ").strip()
password = getpass.getpass("Password: ")

def call(path, token=None, data=None, method=None):
    headers = {"Content-Type": "application/json"}
    if token:
        headers["Authorization"] = "Bearer " + token
    request = urllib.request.Request(
        base + path, headers=headers, method=method,
        data=None if data is None else json.dumps(data).encode(),
    )
    with urllib.request.urlopen(request, timeout=60) as response:
        return json.load(response)

token = call("/api/v1/auth/token", data={
    "username": username, "password": password
})["access_token"]
del password
projects = call("/api/v1/projects", token)["projects"]
print("Available projects:", ", ".join(p["name"] for p in projects))
name = input("Project name: ").strip()
project_id = next(p["id"] for p in projects if p["name"] == name)
project = call("/api/v1/projects/" + project_id, token)
metadata = project["metadata"]
scope = {"version": 1, "include_paths": ["."], "test_paths": ["tests"]}
metadata.setdefault("audit", {})["scope"] = scope
call("/api/v1/projects/" + project_id, token,
     data={"metadata": metadata}, method="PUT")
saved = call("/api/v1/projects/" + project_id, token)
assert saved["metadata"]["audit"]["scope"] == scope
print("Saved scope:", json.dumps(scope))

The script accepts HTTPS URLs and local loopback HTTP URLs only. It rejects credentials embedded in the URL before requesting a password. Use this example only for an approved project-scope change.

The example reads existing metadata and preserves other fields, including the architecture policy. Coordinate the update with colleagues; do not edit this object concurrently. Then start a new audit through the UI or Swagger: POST /api/v1/traceability/projects/{project_name}/audit-report-jobs, with {"language":"en","force_refresh":true} and your Bearer token. Use the project name returned by the API; UUIDs are used only for /api/v1/projects/{id} requests.

Poll GET /api/v1/traceability/audit-report-jobs/{id} using the job id returned by the start request. A scope change requires a new CPG freshness check even without a new Git commit. Check source_revision and scope_digest in the downloaded report and its manifest. Download the report using download_url and check analysis completeness. For report_quality_status: "incomplete", use the report to diagnose the run: find sections marked unsupported, not_measured or timeout and their reasons. These identify an unsupported check, an absent measurement or an expired execution deadline. Use the reasons to prepare the next run. When score_eligible: false, the overall score is unavailable.

A job with status: "failed" and report_quality_status: "incomplete" can provide a diagnostic report. If the response contains a nonempty download_url, download it with the same Bearer token. If the link is empty, use error, report_quality_reason and stage_history to identify the cause and prepare the next run.

Audit report directory

Markdown reports and their integrity manifests are stored in dashboard.audit_report_output_dir. The default is data/dashboard-audit-reports, relative to the server working directory. In the standard Compose deployment this is /app/data/dashboard-audit-reports: the data directory is mounted from the server and survives container recreation.

To select another persistent location, add this parameter to the existing dashboard section of config.yaml, preserving its other settings:

dashboard:
  audit_report_output_dir: data/dashboard-audit-reports

A custom directory must be mounted into the api container as persistent storage and writable by its user. Wait for active audits to finish, then restart the API using the same Compose files as the installed deployment. Run an audit through the UI or REST, download the available report, and repeat the download after recreating the container. Keep each report and its .manifest.json together. The server administrator configures this path in config.yaml.

Optional OpenViking memory

OpenViking supports document search and long-term memory. Embedding maps text to vectors for search, rerank reorders retrieved results, and VLM generates text summaries and handles images when the model supports them. These are separate settings. If you only need CPG and deterministic source audit, disable document import with import_docs: false in REST or --no-docs in the CLI.

On the Ubuntu server, deploy/openviking/ov.local-models.conf sets local embedding and rerank. Check the listed models’ license terms before use. Set these values in the protected .env:

COMPOSE_PROFILES=local-models
OPENVIKING_CONFIG_TEMPLATE=ov.local-models.conf
OPENVIKING_API_KEY=<secret-from-approved-store>

The shipped template configures Yandex VLM by default. For that provider, also set YANDEX_API_KEY and YANDEX_FOLDER_ID in .env. For OpenAI, copy the template and replace its vlm section: set provider: "openai", api_base: "https://api.openai.com/v1", an available model, and an api_key through a secret environment variable. Select the copy using OPENVIKING_CONFIG_TEMPLATE; add the key variable to the openviking service environment and its startup substitution list in Compose. The main API’s GIGACHAT_* variables do not configure OpenViking. GigaChat needs a compatible endpoint with OAuth token refresh or a verified adapter.

After the change, run this on the server from the installation directory:

sudo docker compose -f docker-compose.yml up -d --force-recreate openviking
sudo docker compose -f docker-compose.yml exec -T openviking curl -fsS http://127.0.0.1:1933/health

After /health confirms service availability, import project documentation. Check the import result with codegraph_project_context_sync_status and {}.

Configure automatic project checks

After importing the repository, connect its events. A push webhook supplies new commits for CPG updates; pull request or merge request events start review preparation. Follow the guide for your Git server:

  • GitHub: repository connection, webhooks and pull request review.
  • GitLab: repository connection, webhooks and merge request review.
  • GitVerse: webhooks, synchronization and pull request review publication.
  • SourceCraft: repository coordinates, webhooks and merge request review.

Choose events for the branches you use and verify a test push: wait for the synchronization job, then compare the CPG commit with the repository commit. For a PR/MR, inspect the review result and its publication in the target request.

Architecture control explains how to describe components and allowed dependencies in YAML, validate rules and apply them when checking changes.

To run checks regularly, configure automatic project audits: choose the cadence, time zone, service account and missed-run policy. Verify the first run and its saved report.

Apply and verify a change

  1. Back up the current .env, config.yaml, and project declaration.
  2. Change only the approved values; preserve file owner and restricted permissions.
  3. Restart CodeGraph through the service manager.
  4. Run the shared readiness command from the installation guide.
  5. Verify authentication, project visibility, CPG freshness, and the integration that changed.

For production acceptance, record container health, dependency readiness, access control, source provenance, and connectivity to the customer’s systems after the change.

Troubleshooting

  • Startup rejects the JWT secret: generate a new 64+ character value and update the protected .env file.
  • Browser requests are rejected: compare the exact scheme and host with CORS_ALLOWED_ORIGINS and API_ALLOWED_HOSTS.
  • A provider is unavailable: verify that provider’s secret reference, egress policy, and CA trust; do not disable TLS verification.
  • A setting is unknown: compare it with the exact release’s .env.example and config.yaml instead of editing application source.

Next: Installation · Quick start