Settings
The Settings section is an admin-only area for configuring the code review platform: manage user accounts, create AI reviewer bots, set up Slack and Teams notifications, inspect webhook delivery history, and control licensing. Access it from the top navigation bar when logged in as an administrator.
Overview Free
Navigate to Settings in the top nav bar. All Settings pages share a tab bar at the top — Users / User Stats / AI Prompts / Webhook Deliveries / Review Templates / Notifications / Audit Log — so you can switch sections without going back to the Settings index. A breadcrumb above the tabs always shows where you are.
- Users — list all accounts, create users, AI reviewer bots, or service accounts; edit and delete accounts
- AI Prompts — create and manage the system prompt templates that AI reviewer bots use when analyzing code review diffs
- Notifications — configure Slack, Teams, Email, global Webhook and SMS notifications with per-channel event toggles and message templates
- Webhook Deliveries — inspect every incoming push event, see processing status, and retry failed deliveries
- Audit Log — append-only record of every significant action with actor, target, details, and IP address
- Service Accounts — create token-authenticated machine users for Grafana and other integrations
Users Free
There are two admin user-list pages:
/users— the main user list, accessible from the top navigation. Includes a filter bar: search by name or email, filter by account type (Human / AI Bot / Service Account), and filter by role (Admin / Regular). Live result count updates as you type. Create users, AI bots, and service accounts all from this page./settings/users(Settings → Users tab) — the same list embedded within the Settings area, without the filter bar.
Both pages show the same rich per-row detail: for AI bots — the model name and a trigger mode badge (auto or manual) and the assigned prompt (if any); for service accounts — a token active / no token badge and a Regenerate token link.
Trigger mode
Each AI reviewer bot has a trigger mode that controls when it runs:
| Mode | Behaviour |
|---|---|
| Auto (default) | Runs automatically when assigned to a CR. Also re-runs automatically whenever new commits are added to that CR. |
| Manual | Does not run automatically. An admin or the review author must click Run on the review page to start it. |
Auto bots also have a Re-run button on the review page for on-demand re-execution at any time while the CR is open.
Autofix Extended+
Enable Autofix per bot when creating or editing it. When enabled, any inline suggestion the bot posts shows a purple Autofix button directly on the review page (both in the diff view and in the comments panel).
Clicking the button enqueues a background job (Sidekiq) that:
- Fetches the current file content from the platform API.
- Replaces the flagged line with the suggestion text.
- Pushes a new commit to the review's source branch via the platform API.
- Marks the original comment as resolved and posts a confirmation comment. On failure, posts an error comment instead.
| Platform | Commit API used |
|---|---|
| GitHub | Octokit update_contents |
| GitLab | PUT /api/v4/projects/:id/repository/files/:path |
| Gitea / Forgejo | PUT /api/v1/repos/:owner/:repo/contents/:path |
| Bitbucket Cloud | POST /2.0/repositories/:ws/:repo/src (multipart) |
| Bitbucket Server | PUT /rest/api/1.0/projects/:key/repos/:slug/browse/:path |
| Azure DevOps | POST /_apis/git/repositories/:repo/pushes |
| Gerrit | Not supported |
Autofix only appears on comments that have a single-line suggestion, were written by a bot with Autofix enabled, and have not yet been resolved.
Creating an AI Reviewer bot Free — 1st bot Extended+ — multiple bots
- Click 🤖 New AI Reviewer.
- Enter a bot name (e.g. Claude Reviewer). Username and email are auto-generated if left blank.
- Choose AI Provider:
- OpenAI-compatible (local) — available on all tiers. Enter the base URL (e.g.
http://localhost:11434/v1for Ollama) and model name. - Anthropic Claude Standard+ — enter your Anthropic API key (
sk-ant-…) and select a Claude model. - OpenAI Standard+ — enter your OpenAI API key (
sk-…) and select a GPT model. - DeepSeek Standard+ — enter your DeepSeek API key and select a model (e.g.
deepseek-chat). - Google Gemini Standard+ — enter your Gemini API key (
AIza…) and select a Gemini model. - Qwen / Tongyi Standard+ — enter your DashScope API key and select a Qwen model.
- OpenAI-compatible (local) — available on all tiers. Enter the base URL (e.g.
- Choose Trigger mode: Auto (recommended for most bots) or Manual (useful for expensive models you want to run selectively).
- Optionally select a Review Prompt from the dropdown (see Per-bot assignment below).
- Click Create AI Reviewer. The bot is ready to be assigned to any code review.
AI Prompts Free
AI Prompts are named system prompt templates stored in the database. Each AI reviewer bot can be assigned one prompt; if none is assigned, the default prompt is used.
Managing prompts
Go to Settings → AI Prompts. From here you can:
- Create a new prompt with a name, optional description, and system prompt text.
- Edit any non-built-in prompt — change its name, description, or system prompt body.
- Set as default — mark any prompt as the default. Only one prompt can be default at a time; setting a new default automatically clears the previous one.
- Delete any non-built-in prompt that you no longer need.
- View the full text of the built-in prompt (it cannot be edited or deleted — see below).
Prompt variables Free
Two special placeholders can be used anywhere in the system prompt text. They are substituted at review time, just before the prompt is sent to the AI:
{{languages}}— replaced with a comma-separated list of programming languages detected in the diff (e.g. Ruby, JavaScript, TypeScript). If no language is detected, replaced with unknown.{{guidelines}}— replaced with language-specific review guidelines for each detected language. Codeveira has built-in guideline blocks for Ruby, JavaScript, TypeScript, Python, Go, Java, PHP, C# and Shell. If none match, falls back to a generic best-practice message.
Example prompt using both variables:
You are a senior software engineer performing a thorough code review. Primary languages: {{languages}}. {{guidelines}} ## Universal rules - Flag security vulnerabilities: injection, XSS, CSRF, auth bypass - Identify logic bugs and unhandled edge cases - Note performance problems ## Response format Reply ONLY with a valid JSON array. Each element: { "file_path", "line_number", "severity", "body" } If there are no issues, return exactly: []
Built-in prompt Free
A Default Review Prompt is seeded automatically when the app first starts. It is marked as built-in and carries the same language-specific guidelines that Codeveira used before the prompt management feature was added.
The built-in prompt:
- Has a built-in badge in the prompt list — no Edit or Delete buttons are shown.
- Can be viewed in full by clicking View.
- Can be demoted from default — click Set default on any other prompt to make that one the default instead. The built-in prompt stays in the list but is no longer used automatically.
- Cannot be edited or deleted — this is enforced at both the controller level and the model level (
before_destroycallback).
Per-bot prompt assignment Free
Each AI reviewer bot can have its own prompt assigned independently. This lets you run multiple bots with different review styles — for example a strict security-focused bot and a more lenient style-only bot.
To assign a prompt to a bot (or change its trigger mode):
- Go to Settings → Users and click Edit next to the AI reviewer bot.
- In the AI Reviewer Settings section, choose a prompt from the Review Prompt dropdown and adjust the Trigger mode if needed.
- Save. The bot will use the selected prompt and trigger mode for all future reviews.
You can also assign the prompt when creating a new bot — the dropdown appears in the creation form if at least one prompt exists.
Priority order:
- If the bot has a specific prompt assigned → use that prompt's system prompt (with variable substitution).
- Otherwise → use the prompt marked as default (with variable substitution).
- If no default is set → fall back to the built-in hardcoded guidelines.
Notifications Standard+
Go to Settings → Notifications to configure all notification channels for code review events. Each channel has independent event toggles and fully customisable message templates. Template variables: {{cr_id}}, {{title}}, {{status}}, {{repository}}, {{author}}, {{url}}.
Supported events
- New review — when a push webhook creates a code review
- Assigned — when reviewers are assigned to a review
- Comment — when a comment is posted on a review
- Approved — when all reviewers have approved
- Rejected — when a reviewer rejects
Slack
- In your Slack workspace go to Apps → Incoming Webhooks → Add New Webhook to Workspace.
- Choose the target channel and copy the webhook URL.
- Paste it in Settings → Notifications → Slack and save.
Microsoft Teams
- Open the Teams channel, click ⋯ → Connectors → Incoming Webhook → Configure.
- Copy the generated URL and paste it in Settings → Notifications → Teams.
Configure SMTP credentials via environment variables (SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD, SMTP_FROM). In Settings → Notifications → Email set the sender display name, choose which events send emails, and customise subject templates ({{cr_id}}, {{title}} supported).
Global Outgoing Webhook
In Settings → Notifications → Webhook configure a global HTTPS endpoint that receives a signed JSON payload on selected events. Set an optional secret — each request includes X-Codeveira-Signature: sha256=… (HMAC-SHA256) for verification.
SMS
In Settings → Notifications → SMS configure any HTTP-based SMS provider (SMSAPI, Twilio, Vonage, MessageBird, Infobip…). Set the API URL, authentication token, sender name/number, recipient phone numbers (comma-separated, international format), and the JSON field names the provider expects. Quick-fill presets auto-populate these fields for the most popular providers.
Webhook Deliveries Free
Go to Settings → Webhook Deliveries to see the last 200 incoming webhook events from all connected Git platforms.
*_WEBHOOK_SECRET). Azure DevOps, Gerrit, and SVN don't support HMAC signing on their webhook mechanisms, so AZURE_WEBHOOK_SECRET/GERRIT_WEBHOOK_SECRET/SVN_WEBHOOK_SECRET are instead checked via HTTP Basic Authentication. Either way, leaving the corresponding environment variable blank rejects every request from that platform with 401 Unauthorized rather than accepting it unauthenticated.
Columns
- # — internal delivery ID
- Source — Git platform (gitlab, github, gitea, forgejo, bitbucket, bitbucket_server, azure, gerrit, svn)
- Event — event type string sent by the platform (push, repo:push, git.push, ref-updated, …)
- Status
received— webhook arrived and job was enqueuedprocessed— job completed successfully, CR created or updatedfailed— job raised an error; see the Error column for details
- Received — time the webhook arrived (hover for exact timestamp)
- Error — exception message, truncated; hover for full text
Retrying a delivery
Click Retry next to any delivery. This creates a new delivery record and re-enqueues ProcessPushJob with the original payload. The new record goes through the same received → processed / failed lifecycle as a live delivery.
processed delivery is safe — ProcessPushJob deduplicates commits by SHA, so no duplicate CRs or commits are created.
Audit Log Extended+
Available at Settings → Audit Log. Records every significant action performed in the code review platform — append-only, never editable.
What is logged
| Action | Trigger |
|---|---|
| Reviews | |
review.created | Manual CR creation |
review.approved / rejected | Reviewer decision |
review.closed / reopened | Author or admin changes status |
review.merged | Two or more CRs merged into one new CR |
review.reviewers_updated | Reviewers added or removed; details list added/removed names |
review.commits_added | Follow-up commits added to an open CR |
review.ai_triggered | AI bot review manually started |
review.deleted | Review destroyed |
| Comments | |
comment.created | General or inline comment posted |
comment.resolved | Comment marked resolved or unresolved |
comment.label_added / label_removed | Label toggled on a comment |
comment.labels_cleared | All labels removed from a comment at once |
| Users | |
user.created | New user created by admin |
user.updated / deleted | User profile saved or account removed |
user.password_changed | Password changed from profile |
user.api_token_regenerated | API token regenerated |
user.ai_bot_created | New AI bot account created |
user.service_account_created | New service account created |
| Repositories | |
repository.created / updated / deleted | Repository management |
repository.member_added | Member granted access to a repository |
repository.member_role_changed | Member role changed (viewer / reviewer / admin) |
repository.member_removed | Member removed from a repository |
| AI Prompts | |
ai_prompt.created / updated / deleted | Prompt template created, edited, or removed |
ai_prompt.set_default | A prompt template set as the default |
| Settings & Webhooks | |
settings.notifications_updated | Chat webhook URLs saved |
webhook.retried | Webhook delivery manually retried |
Each entry contains
- Time — timestamp of the action
- Actor — display name of the user who performed the action (snapshot at time of event)
- Action — dot-separated
category.verbwith colour-coded category badge - Target — human-readable label of the affected object (CR ID, username, repository name)
- Details — structured extra context (title, changed fields, provider, etc.)
- IP — real client IP; reads
X-Forwarded-Forautomatically when behind nginx
Filtering
Use the Actor dropdown to filter by a specific user, and the Action dropdown to filter by category: review, user, repository, settings, webhook, ai_prompt, or comment. Each category is colour-coded in the table. Shows up to 500 most recent events.
Export Enterprise
Use the CSV and JSON buttons in the top-right corner of the Audit Log page to download the currently filtered view. Exports up to 10 000 events (no 500-event cap). Both formats include all fields: id, timestamp, actor, action, target, details, and IP address.
- CSV — suitable for Excel, Google Sheets, or importing into a SIEM
- JSON — one object per line, suitable for scripting or log ingestion pipelines
Webhook forwarding Enterprise
Every audit event can be forwarded in real-time to an external HTTP endpoint. Configure the URL in Settings → Audit Log → Webhook Forwarding. Codeveira POSTs a JSON payload for each event asynchronously — the webhook call never blocks the original user action.
The payload includes a "source": "codeveira" field so you can filter Codeveira events when multiple systems share the same endpoint.
Compatible receivers
- Logstash — use the
httpinput plugin, point Codeveira tohttp://logstash:8080 - Elasticsearch — use Elastic Agent with an HTTP input, or route through Logstash to an ingest pipeline
- Splunk — use the HTTP Event Collector (HEC) endpoint
- Datadog — use the Datadog log intake HTTP endpoint
- Graylog / Fluentd / any SIEM — any receiver that accepts POST with
Content-Type: application/json
Timeout: 5 s connect, 10 s read. Failed deliveries are logged to Rails.logger (not retried automatically). Remove the URL to disable forwarding.
Rails.logger and the original action completes normally.
Two-Factor Authentication Standard+
Two-factor authentication (2FA) adds a second verification step after password login using a TOTP authenticator app (Google Authenticator, Authy, 1Password, etc.). AI bots and service accounts are exempt.
Global enforcement (admin)
Go to Settings → Users. A panel at the top of the page lets you enable or disable the global 2FA requirement:
- When enabled: users who have not yet configured 2FA are redirected to the setup page immediately after login. Users cannot disable their own 2FA while this is active.
- When disabled: 2FA is optional — users can choose to enable or disable it themselves from their profile.
The Users list shows a green 2FA badge next to every account that has 2FA configured.
User self-enrollment
- Go to Profile → Two-Factor Authentication.
- Click Set up 2FA.
- Scan the QR code with your authenticator app, or type the key manually.
- Enter the 6-digit code shown in the app and click Enable 2FA.
Login flow
After entering the password, a verification screen prompts for the current 6-digit TOTP code. Codes are valid for 30 seconds with a ±30 s drift window to account for clock skew.
Outgoing Webhooks Free
Not to be confused with the single Global Outgoing Webhook above (Settings → Notifications → Webhook), which is a chat-style notification channel alongside Slack/Teams/SMS. This section is a separate system, purpose-built for task-tracker/automation integration:
- Settings → Outgoing Webhooks (global admin) — the default every repository fires against out of the box. One config for the whole instance.
- A repository only needs its own instead if it must notify a different endpoint/tracker: enable "Use this repository's own outgoing webhooks" on the repository's Edit page, and its own Webhooks tab (repository page → Webhooks) then takes over completely for that repository, ignoring the global list. Any number of webhooks either way, each subscribed to a different set of events.
Events
review.opened, review.approved, review.rejected, review.closed, review.reopened, comment.created, symbol.changed (fires when a watched symbol's signature changes on the default branch — no review/actor in this payload, it uses its own envelope with a symbol key instead). An optional secret token enables X-Codeveira-Signature: sha256=… (HMAC-SHA256) on every delivery.
Task tracker integration (do-it-yourself, or see native Task Trackers below)
For any tracker without a native connector — Linear, Azure Boards, or anything else — this is the standardized, vendor-neutral way to connect Codeveira to it. Every payload includes:
ticket_keys— every ticket key found in the CR's title and branch name (e.g.["PROJ-123"]for a title like[PROJ-123] Fix the thing, or a branch likefeature/PROJ-123-fix-thing). Matches thePROJECT-123convention shared by Jira/YouTrack/Linear by default — override the pattern per repository under the repository's Edit page for trackers keyed differently (e.g. a bare#123).review.url— a direct link back to the CR, ready to post as a comment with no reconstruction needed.
Wiring a tracker up is a config change on its side, not a Codeveira feature request: an incoming-webhook rule or a Zapier/Make "Webhooks" recipe — the payload shape never changes.
{
"event": "review.opened",
"review": { "id": 42, "cr_id": "CR-REPO-42", "title": "[PROJ-123] Fix the thing", "status": "open", "url": "https://codereview.example.com/repositories/1/reviews/42" },
"repository": { "id": 1, "name": "my-repo" },
"actor": { "id": 7, "name": "Jane Doe" },
"ticket_keys": ["PROJ-123"]
}
Task Trackers Standard+
Unlike Outgoing Webhooks above, which only sends data out and needs the tracker's own automation to act on it, Task Trackers actually transitions the ticket and posts a comment back — no receiving script to write on YouTrack/Jira/Mantis/Bugzilla's side. Same global/override shape as Outgoing Webhooks:
- Settings → Task Trackers (global admin) — the default every repository syncs against out of the box. One config for the whole instance.
- A repository only needs its own instead if it must sync with a different tracker instance: enable "Use this repository's own task trackers" on the repository's Edit page, and its own Task Trackers tab then takes over completely for that repository.
Configuration
- Tracker type — YouTrack, Jira, Mantis, or Bugzilla.
- Base URL and API token — validated against the same SSRF guard as outgoing webhook URLs, re-checked again at request time. Jira also needs the account email, since Jira Cloud authenticates with Basic Auth (
email:api_token), not the token alone. - Status mapping — per event (
review.opened/approved/rejected/closed/reopened), the target ticket status. Bugzilla also takes a separate resolution field, since closing a Bugzilla bug setsstatusandresolutiontogether in one request. - Post comment — when enabled (default), also posts a comment on the ticket linking back to the review.
An event with no status mapping is skipped for the transition but still gets a comment (if enabled). Use Test Connection on the index page to verify the base URL and credentials before relying on it.
Per-tracker behavior
- YouTrack — applies the target state name directly, no lookup call needed.
- Jira — looks up the issue's real available transitions and matches the configured target name case-insensitively; fails with a clear error listing the real available names if there's no match.
- Mantis — validates the target status against the project's status enum before applying it. The Mantis REST API must be enabled server-side (
$g_rest_api_enabled = ON) — a disabled/unreachable API surfaces as a clear connection error, not a silent no-op. - Bugzilla — sets
statusandresolutiontogether in one request.
Mantis and Bugzilla both key issues by a bare number (12345), not a PROJECT-123-style key — set a matching ticket-key-pattern override on the repository (the same setting ticket_keys extraction above uses) so Codeveira can find them in review titles/branches.
Service Accounts Standard+
Service accounts are machine users with no password login — they authenticate exclusively via a Bearer token. They are designed for external tools such as Grafana, Prometheus, or monitoring scripts that need read access to the /metrics endpoint.
Creating a service account
- Go to Settings → Users and click 🔑 New Service Account.
- Enter a display name (e.g. Grafana) and click Create Service Account.
- The API token is shown once in a green banner with a Copy button. Save it somewhere safe — it cannot be retrieved again.
Managing tokens
Service accounts appear in the Users list with a 🔑 icon and a token active / no token badge. To rotate the token, click Regenerate token — the old token stops working immediately.
/metrics endpoint only. They cannot log in to the web UI or access any other part of the API.
Prometheus Metrics Extended+
Codeveira exposes a Prometheus-compatible metrics endpoint at GET /metrics. It returns plain text in Prometheus exposition format 0.0.4 and requires a valid service account Bearer token.
Authentication
Pass the service account token in the Authorization header:
Authorization: Bearer <service-account-token>
Requests without a valid token receive 401 Unauthorized with a WWW-Authenticate: Bearer challenge.
Grafana datasource setup
In Grafana, add a Prometheus data source:
- Set URL to your Codeveira instance, e.g.
https://codeveira.example.com - Under Custom HTTP Headers, add:
Header:AuthorizationValue:Bearer <token> - Set Scrape interval to
60sor longer — metrics are live queries, not pre-aggregated.
Available metrics
| Metric | Type | Description |
|---|---|---|
codeveira_reviews_total{status} | gauge | All-time review count by status (open, approved, closed, rejected) |
codeveira_reviews_open | gauge | Currently open reviews (all repos) |
codeveira_reviews_stale | gauge | Open reviews older than 7 days |
codeveira_repository_reviews_open{repository} | gauge | Open reviews per repository |
codeveira_reviews_created_24h | gauge | Reviews created in the last 24 hours |
codeveira_cycle_time_p50_seconds{repository} | gauge | Median cycle time in seconds, last 30 days |
codeveira_cycle_time_p90_seconds{repository} | gauge | p90 cycle time in seconds, last 30 days |
codeveira_webhook_deliveries_total{status} | gauge | All-time webhook deliveries by status |
codeveira_webhook_failures_24h | gauge | Failed webhook deliveries in the last 24 hours |
codeveira_comments_24h | gauge | Comments posted in the last 24 hours |
codeveira_users_total{type} | gauge | Users by type: human, ai_bot, service_account |
codeveira_audit_events_24h{category} | gauge | Audit events in the last 24 hours by category |
codeveira_reviewer_pending_assignments{reviewer} | gauge | Open reviews currently awaiting each human reviewer (bots/service accounts excluded) |
codeveira_reviewer_stale_assignments{reviewer} | gauge | Assignments still pending after 7 days — the clearest "who's blocking things" signal |
codeveira_reviewer_decision_time_p50_seconds{reviewer} | gauge | Median time from assignment to approve/reject, last 30 days |
codeveira_reviewer_decision_time_p90_seconds{reviewer} | gauge | p90 time from assignment to approve/reject, last 30 days |
codeveira_scrape_duration_seconds | gauge | Time taken to collect all metrics |
docker-compose.monitoring.yml is a ready-made, opt-in Prometheus + Grafana + Loki overlay (docker compose -f docker-compose.yml -f docker-compose.monitoring.yml up -d) with two dashboards already provisioned — Review Health & Bottlenecks (the metrics above) and Nginx — Connections & Security (who's connecting, and any failed/suspicious requests by IP, sourced from nginx's own access log rather than a Prometheus label). See the deploy repo's README for setup.
nginx requirement
If Codeveira runs behind nginx, include X-Forwarded-For in your proxy config so the Audit Log records real client IPs (not the proxy address):
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
The bundled nginx container already sets this by default. If you're running your own reverse proxy instead, see the installation guide for a full nginx config example.
Backup & Restore Standard+
The Backup & Restore tab lets you protect your PostgreSQL database without any external tooling. Backups are stored in a dedicated Docker volume (backup_data:/backups) that is mounted in both the app and sidekiq containers.
Scheduled backups
Select a preset schedule or enter a custom cron expression. Available presets: Hourly, Every 6 h, Daily at 2 am, Weekly on Sunday at 2 am. The schedule is stored in the database and loaded into sidekiq-cron at startup. To disable automatic backups, select Disabled.
Set a Retention count (default 7). After each successful backup the oldest files beyond the retention limit are automatically deleted.
Manual backup
Click Run backup now to enqueue an immediate DatabaseBackupJob. The job runs in the backup Sidekiq queue and does not block the web process. A live spinner banner appears while the backup is running; it turns green with the filename when complete and the page reloads automatically.
Upload backup
Drag and drop a .dump file onto the upload zone, or click Choose file to pick one from disk. The file is streamed to the backup volume and appears in the list immediately, ready to restore. Maximum upload size is 512 MB (set by client_max_body_size in nginx).
Backup list
All .dump files in the backup volume are listed with filename, size, and creation date. For each file you can:
- Download — streams the file to your browser as
application/octet-stream. - Restore — runs
pg_restore --clean --if-existsin a background job. A full-screen overlay with a spinner appears during the restore. When finished, the overlay transitions to a green confirmation; click OK to reload the page. The application stays up during restore, but plan a brief maintenance window for data consistency.
Environment variables
| Variable | Default | Description |
|---|---|---|
BACKUP_DIR | /backups | Path inside the container where dump files are written |
DATABASE_URL | required | PostgreSQL connection string used by pg_dump and pg_restore |
Domain & HTTPS Free
Codeveira ships with a built-in nginx reverse-proxy container fronting the app on ports 80/443 — no separate reverse proxy to install. It boots with a zero-config self-signed certificate, so this page's job is entirely about switching to a real domain and certificate; unlike most other Settings pages, it's available on every license tier, since it's core self-hosting infrastructure rather than a paid feature.
Modes
- Upload my own certificate — paste in a PEM certificate/private key pair from any CA. Applied immediately, no restart needed.
- Let's Encrypt — HTTP-01 — the simplest automatic option. Requires this server to be reachable on port 80 from the public internet, since Let's Encrypt validates ownership by fetching a token over plain HTTP.
- Let's Encrypt — DNS-01 — validates ownership via a DNS TXT record instead, so it works without exposing port 80 at all, and supports wildcard domains. Supported providers: Cloudflare, AWS Route 53, and Google Cloud DNS — each with its own credential fields shown once selected.
Renewal
Certificates issued via either Let's Encrypt mode renew automatically — a background job runs twice a day and only actually re-issues when the current certificate is within its renewal window, so this needs no attention after initial setup. An Issue / renew now button is available for forcing an immediate attempt (useful right after first configuring DNS-01 credentials, to confirm they work without waiting for the next scheduled run).
Removing a domain
Remove domain clears the configured domain, mode, and any saved DNS credentials, and reverts nginx to its self-signed default — useful if you're moving the instance to a different domain or tearing down a test configuration.
nginx container and volumes fit together, and how to run your own reverse proxy in front of Codeveira instead if you'd rather do that.
Smart Reviewer Suggestions Standard+
Codeveira analyses the git history it has already stored in its database to identify the developers who know each changed file best. No extra Git platform API calls are made — everything is derived from the commits table diffs that were ingested when reviews were created.
How it works
- When a review is processed,
UpdateOwnershipStatsJobparses the stored diffs and upserts per-(repository, file path, author email) commit counts into thefile_ownership_statstable. - When a review page loads,
CodeOwnershipServicequeries the stats for all files in the review, aggregates by author (sum of commit counts × number of files touched), matches emails to Codeveira users, excludes bots, service accounts, and already-assigned reviewers, and returns the top 5. - Suggestions are shown below the reviewer list as a "Suggested by code history" panel with name, file count, commit count, and an Add button.
- Clicking Add assigns the reviewer instantly via Turbo Stream — no full page reload.
Notes
- Only commits already ingested by Codeveira count. Stats accumulate over time as more reviews flow in.
- Author matching uses email (case-insensitive). A developer who commits with a different email than their Codeveira account will not appear until the emails match.
- Deleted files are excluded from ownership tracking.
Upsource Import Enterprise
The Upsource Import tab provides a 5-step migration wizard that imports code reviews, reviewer assignments, and comments from a JetBrains Upsource server into Codeveira.
Step 1 — Connect
Enter the base URL of your Upsource server (e.g. https://upsource.yourcompany.com) and authentication credentials.
Test connection
Before entering credentials, click Test connection next to the URL field. Codeveira sends an HTTP probe from the application server (not your browser) to /~rpc/ on the provided URL and returns an immediate result:
- ✓ Reachable — server responded, safe to proceed.
- ✗ Connection refused — wrong host/port, or the service is down.
- ✗ Timeout — firewall is silently dropping packets; check network routing between Codeveira and Upsource.
- ✗ DNS error — hostname cannot be resolved from the server's network.
This is especially important when the admin accesses the panel remotely via VPN while the Codeveira server has a different network path to the Upsource host.
Credentials
Two authentication formats are accepted:
- Permanent token (recommended) — generate in Upsource Hub under Profile → API Tokens and paste as-is. Sent as a
Bearertoken. The field is masked (type="password") to prevent accidental leaks during screen sharing. - username:password — sent as HTTP Basic auth. Not recommended for production environments.
On submit, the button disables and shows a spinner (large instances may take 5–10 s). Codeveira calls /~rpc/getProjects and /hub/api/rest/users to fetch the full project and user lists.
Step 2 — Map Projects
Each Upsource project is listed with a dropdown to select the target Codeveira repository. Projects are pre-matched by name similarity (normalized, case-insensitive, ignores hyphens and underscores). Select Skip to exclude a project from the import.
Step 3 — Map Users
Each Upsource Hub user is listed with their name, login, and email. Codeveira pre-fills the dropdown for users whose email address exactly matches a Codeveira account (marked ★). Users mapped to Skip are imported without author attribution (shown as "Deleted user").
Step 4 — Options
| Option | Values | Default |
|---|---|---|
| Review states | All / Open only / Closed only | All |
| Date range | From / To (optional) | Unlimited |
| Inline code comments | Checkbox | Off |
Clicking Start import enqueues a UpsourceImportJob in Sidekiq and redirects to the progress page.
Step 5 — Progress
The page polls GET /settings/upsource_import/progress every 3 seconds and updates the progress bar and counter in real time. Per-review errors (e.g. missing data, API timeout) are collected and shown without stopping the overall import. When the job finishes (or fails fatally), the page reloads automatically and shows a summary with links to view the imported repositories.
Idempotency
Each imported review stores the original Upsource review ID in the source_id column. Re-running the wizard skips reviews that are already present. This means the import is safe to run multiple times — useful if the first run encountered errors or if new reviews were created in Upsource after the initial migration.
Limitations
- File-level diff content is not imported — only review metadata, participant assignments, and comments.
- The Hub API must be accessible from the Codeveira server at the same base URL. If Hub runs on a separate hostname, Step 3 will show an empty user list.
- Inline comments require the Upsource feed to include
fileInRevision.fileNameandstartLine(available in Upsource 2021.2+).
Teams Standard+
A Team groups users across every repository — closing a gap where reviews could only be scoped per-individual or per-repo, with no way to ask "what does my team own that's stuck, across every repo it touches."
Managing teams
Under Settings → Teams (global admin), create, rename, or delete a team, then open it to add or remove members and set each member's role — member or lead. Every membership change is recorded in the audit log.
The team rollup
Any team member or lead — no admin access required — gets a Teams link in the top navigation pointing at that team's cross-repo rollup: open, stale, and needs-response reviews and pending assignments across every member's repositories, plus per-member stats (reviews authored, approvals given, comments posted, last active). A global admin can open any team's rollup without being a member of it.
Review Watchers Standard+
Any user can watch a code review without being assigned as a reviewer. Watchers receive all notifications (new comments, status changes) but are not required to approve. The Watch button appears in the action bar on the review page.
Useful for: team leads who want visibility without being in the approval chain; authors of related code who want context; QA engineers tracking a feature branch.
CI Integration Enterprise
Connect your CI system to Codeveira so build results appear directly on review pages as live status badges — updated in real-time via Turbo Streams.
Setup
- Go to Settings → CI Integration and generate a secret token.
- Add the token to your CI system as a secret (e.g.
CODEVEIRA_CI_TOKEN). - At the end of each CI job, POST the build result to
POST /webhooks/ci.
Payload
{
"commit_sha": "abc1234...", // required
"status": "success", // pending | running | success | failed | canceled
"pipeline_name": "Build", // optional, defaults to "CI"
"build_url": "https://...", // optional — shown as "View" link
"provider": "jenkins" // optional — informational
}
Codeveira looks up the commit SHA, finds the associated review, upserts the status, and broadcasts the badge update to any connected browsers.
Compatible CI systems
Any system that can run a shell command or HTTP request: Jenkins, GitHub Actions, GitLab CI, CircleCI, Buildkite, TeamCity, Woodpecker CI, Drone CI, and more. See the Settings → CI Integration page for ready-to-paste examples.
Code Coverage Enterprise
Upload a coverage report from your CI test run and Codeveira overlays it directly on the diff view — a green stripe on covered lines, red on uncovered, in both combined and side-by-side views. Codeveira never runs your tests or compiles anything itself here — it's pure ingest and display of a report CI already produced.
Setup
Uses the same secret token as CI Integration above. POST to /webhooks/ci/coverage as a multipart form with commit_sha, optional pipeline_name/format, and the report file.
Supported formats
Auto-detected from content, or passed explicitly via the format field:
lcov— nyc/istanbul (JS/TS), gcov/lcov (C/C++)jacoco— JaCoCo XML (Java/Kotlin)cobertura— Cobertura XML, also an export option from Python's coverage.py and PHPUnitsimplecov— SimpleCov.resultset.json(Ruby)go_cover—go tool coverprofile (Go)
A summary card on the review page shows the coverage percentage, lines covered/total, format, and pipeline name — with a warning if the report predates the review's current HEAD commit.
SAST Findings Enterprise
Generic ingestion of SARIF 2.1.0 reports — the JSON standard emitted by Semgrep, CodeQL, Bandit, Brakeman, Trivy, Checkov, and effectively every modern SAST/security scanner — instead of a bespoke adapter per vendor.
Setup
Uses the same secret token as CI Integration above. POST to /webhooks/ci/sast as a multipart form with commit_sha, optional pipeline_name, and the report file.
How findings are shown
Each finding is posted as a real inline review comment from a dedicated sast-bot account, at the exact file/line SARIF reports — 🔴 error, 🟡 warning, 🔵 note — deduped so re-uploading the same report doesn't repost. A summary card on the review page shows total findings by severity, tool name, and pipeline name, with a staleness warning if the report predates the review's current HEAD commit.
Architectural Lint & Duplicate Code Detection Standard+
Two independent checks, both off by default, both configured on the same Settings → Architectural Lint page (one toggle each), both posting inline review comments from a dedicated bot account.
Architectural Lint
Runs a small, fixed set of structural rules against every changed file on push. Ruby and TypeScript's own checks use the same tree-sitter parse the symbol indexer already does — no extra pass, no LLM call: string interpolation passed into where/execute/find_by_sql (SQL injection risk) for Ruby, an explicit any annotation for TypeScript. Go, Python, PHP, Java, Kotlin, Ruby, and JavaScript are additionally checked by real external linters — golangci-lint, Pylint, PHP_CodeSniffer (running the phpcs-security-audit standard: SQL injection, eval()/exec(), remote file inclusion, weak crypto, and more), PMD, detekt, RuboCop (its whole Security department), and ESLint (no-eval, no-implied-eval, and more, run against our own bundled config, never the target's) — running in a dedicated, isolated lint-runner container. All run fully offline: only checks confirmed not to need the target repository's own dependencies installed are enabled, so nothing is fetched over the network and no target code is ever executed — same trust model as the tree-sitter rules next to them. Posts as Lint Bot.
Duplicate Code Detection
Flags a changed method that's near-identical to another method anywhere else in the repository. Every function/method-sized definition (4+ lines) the tree-sitter indexer already extracts gets fingerprinted — a hash of the body only, with whitespace normalized — so a duplicate is simply another definition sharing that fingerprint in the same repository and branch. No separate scan, no external tool: it reuses data the indexer is already producing. Catches exact-after-formatting duplicates, not a version with renamed variables throughout. Posts as Duplicate Bot.
Semantic Search Standard+
Natural-language code search — type "where do we handle JWT tokens" into ⌘K/Ctrl+K and get back matching functions, not just repos/reviews/commits by exact substring. An upgrade to Cmd+K search, not a replacement for Find Usages/Go to Declaration (those stay exact and name-based).
Setup
Configure under Settings → Semantic Search: point it at a self-hosted Ollama instance (or any Ollama-compatible /api/embeddings endpoint) and an embedding model (default mxbai-embed-large, must already be pulled). No code ever leaves your infrastructure — the URL is validated against the same SSRF rules as other admin-configured provider URLs. Off by default until configured.
How it works
Every function/method-sized definition the tree-sitter indexer already extracts gets embedded asynchronously after each push, so a slow or unreachable embeddings API never blocks push processing. Search results rank by cosine similarity, computed in application code against the existing symbol index — no pgvector extension or separate vector database required.
License All tiers
Codeveira is free for unlimited users with local AI models — no license key required. A license key unlocks cloud AI providers and advanced features.
Tiers
| Tier | Price | Users | License key | Included features |
|---|---|---|---|---|
| Free | $0 | Unlimited | Not required | Core review, 1 AI bot (local model only), email notifications, IDE diagnostics |
| Standard | $10/user/mo | Unlimited | Required | + cloud AI providers (Claude, OpenAI, DeepSeek, Gemini, Qwen), Compare, Teams, Slack/Teams, REST API, service accounts, IDE plugins, Backup & Restore, Upsource Import, 2FA |
| Extended | $14/user/mo | Unlimited | Required | + multiple AI bots, Autofix, LDAP/AD, Audit log, Prometheus metrics |
| Enterprise | $16/user/mo | Unlimited | Required | All features, including Code Coverage overlay and SAST findings (SARIF) |
Entering a license key
- Go to Settings → License (admin only).
- Paste the license key into the text field and click Activate License.
- The current tier, paid seat count, customer name, and expiry date are shown immediately after activation.
The key is verified offline — no internet connection is required. If the key is invalid or expired, an error is shown and the previous license remains active.
Removing a license
Click Remove License on the License settings page. The instance reverts to the Free tier. All users remain active; only the unlocked features become unavailable until a valid license is applied again.
User limit enforcement
The limit is enforced at registration time. If the current number of human users equals or exceeds the tier's limit, creating new users (via the admin panel, LDAP sync, or API) is blocked with an error message explaining which tier is active.