Meerkat Technical Reference

Everything you need to install, configure, and integrate Meerkat into your Git hosting environment.

Overview

Meerkat is a dependency-tracking platform for your Git repositories. It scans repositories across configured repository groups, extracts all project dependencies, and presents them through a web interface — enabling rapid identification of which projects are affected when a package has a known security threat.

Key capabilities:

  • Projects Dashboard — view all scanned projects with their dependencies, versions, and ecosystems
  • Hunt — search for packages across all repos to identify exposure instantly
  • Allow List & Policy Enforcement — curate approved dependencies and enforce them via CI
  • Vulnerability Threat Feed — auto-subscribe to malware reports from a vulnerability intelligence feed
  • CI Agent — gate CI pipelines on policy compliance
  • Notifications — email and chat alerts for violations and new malware

Prerequisites

Before deploying Meerkat, ensure you have:

  • Docker and Docker Compose installed
  • A Git hosting platform Personal Access Token (PAT) with read_api scope
  • A PostgreSQL database (provided automatically by the devcontainer)
  • OIDC client credentials from your identity provider

For local development, VS Code with the Dev Containers extension is recommended — no local tool installation required.

Quick Start

The fastest way to run Meerkat locally is via the VS Code devcontainer:

1. Clone the repository

terminal bash
git clone https://git.internal/your-group/meerkat.git
cd meerkat

2. Create your .env file

terminal bash
cp .env.example .env
# Edit .env and fill in real values

3. Open in devcontainer

Open the project folder in VS Code. When prompted, click "Reopen in Container". The devcontainer will build the Go backend and PostgreSQL services, run DB migrations, and install all required tooling automatically.

4. Start the server

terminal (inside devcontainer) bash
cd backend && go run main.go

The server will be available at http://localhost:8080.

Static pages can also be previewed without a running server by opening frontend/index.html directly in a browser. The contact form requires the Go backend.

Environment Variables

All secrets must be provided via a .env file (gitignored). Copy .env.example to get started. Non-secret configuration lives in config.yaml.

Variable Required Description
GIT_HOST_URLYesGit hosting platform instance base URL
GIT_HOST_TOKENYesPersonal Access Token with read_api scope
WEBHOOK_SECRETYesShared secret for CI webhook authentication
DATABASE_URLYesPostgreSQL connection string: postgresql://user:pass@host:port/db
ADMIN_USERSNoComma-separated OIDC preferred_username values for admin role
THREAT_FEED_ENABLEDNoEnable vulnerability threat feed (true/false, default: true)
THREAT_FEED_POLL_INTERVALNoHow often to poll the threat feed (Go duration, default: 1h)
EMAIL_TENANT_IDNotificationsEmail API tenant ID
EMAIL_CLIENT_IDNotificationsApp registration client ID with mail-send permission
EMAIL_CLIENT_SECRETNotificationsApp registration client secret
EMAIL_SENDERNotificationsMailbox UPN/object ID the app sends as
CHAT_WEBHOOK_URLChatBase URL of the team chat server
CHAT_USERNAMEChatBot account username
CHAT_PASSWORDChatBot account password
MEERKAT_BASE_URLNoPublic base URL embedded in notification emails
NOTIFICATIONS_DEV_OVERRIDENoRedirect all email notifications to this address in dev
TENANT_SCAN_ENABLEDNoMaster switch for tenant-wide scanning (default: true)
INCREMENTAL_SCAN_ENABLEDNoSkip unchanged projects in scans (default: true)

Authentication & Roles

Meerkat uses OpenID Connect (OIDC) for authentication. All routes require authentication except /docs, /openapi.yaml, and /metrics.

Roles

RoleDescription
admin Full access — can trigger scans, manage deny/allow list entries and enforcements, and access all pages.
reader Read-only access — can view all pages but cannot trigger scans or modify list entries.

The ADMIN_USERS variable accepts a comma-separated list of OIDC preferred_username values (case-insensitive). Users whose username matches an entry are assigned the admin role; all others get reader. If ADMIN_USERS is unset, all authenticated users are treated as admins.

.env env
ADMIN_USERS=jalexander,jdoe

CI Agent — Setup

The Meerkat CI agent is a single static Go binary distributed as a container image (meerkat-ci-agent:latest). Add the following stage to any project's .ci-pipeline.yml:

.ci-pipeline.yml yaml
meerkat-scan:
  stage: test
  image: registry.internal/internal/meerkat-ci-agent:latest
  variables:
    MEERKAT_URL: "https://meerkat.internal"
    MEERKAT_SECRET: $MEERKAT_WEBHOOK_SECRET
  script:
    - meerkat-ci-agent --output meerkat-report.json
  artifacts:
    paths:
      - meerkat-report.json
    when: always
    expire_in: 30 days
  allow_failure: false

CI_PROJECT_ID is provided automatically by your CI platform — no extra configuration needed.

CI Agent Environment Variables

VariableSourceDescription
MEERKAT_URLPipeline configBase URL of the Meerkat instance
MEERKAT_SECRETCI/CD variableWebhook shared secret (must match WEBHOOK_SECRET)
CI_PROJECT_IDCI platform (auto)Numeric project ID
CI_PIPELINE_IDCI platform (auto)Included in artifact for traceability
CI_JOB_IDCI platform (auto)Included in artifact for traceability

CI Agent — Flags & Exit Codes

Flags

FlagDefaultDescription
--allow-failurefalseExit 0 even when denied dependencies are found (warn-only rollout mode)
--output <path>noneWrite the full JSON response as a CI artifact
--timeout <secs>300HTTP request timeout in seconds

Exit Codes

CodeMeaning
0 Pass — scan succeeded, no deny-list or allow-list violations
1 Fail — denied or unapproved dependencies found, or unexpected error
2 Timeout — scan did not complete within the allowed time

CI Agent — Artifact Output

When --output is specified, the agent writes a JSON file wrapping the scan response with CI metadata:

meerkat-report.json json
{
  "http_status": 200,
  "timestamp": "2026-04-09T11:00:00Z",
  "ci_project_id": "42",
  "ci_pipeline_id": "12345",
  "ci_job_id": "67890",
  "result": {
    "status": "pass",
    "project_id": 1,
    "project_name": "my-app",
    "violations": [],
    "violation_count": 0,
    "allow_list_violations": [],
    "allow_list_violation_count": 0,
    "allow_list_enforced": false,
    "scan_status": "success",
    "dependency_count": 87,
    "message": "Scan completed. No policy violations found."
  }
}

Supported Package Ecosystems

Meerkat extracts dependencies from the following manifest file types:

npm / yarn
package.json
yarn.lock
package-lock.json
Python
requirements.txt
pyproject.toml
Pipfile / Pipfile.lock
Go
go.mod
go.sum
Ruby
Gemfile
Gemfile.lock
Java
pom.xml
build.gradle
PHP
composer.json
composer.lock
Rust
Cargo.toml
Cargo.lock
.NET
*.csproj
packages.config

API Reference

All endpoints are under /api/v1/. Full interactive documentation is available at /docs (Swagger UI) and the raw schema at /openapi.yaml.

MethodPathDescriptionAuth
GET/api/v1/projectsList all scanned projectsRequired
GET/api/v1/projects/:id/dependenciesList dependencies for a projectRequired
POST/api/v1/huntSearch packages across all projectsRequired
POST/api/v1/webhooks/scanCI webhook to trigger rescanSecret
GET/api/v1/allow-listList approved packagesRequired
POST/api/v1/allow-listCreate allow list entryAdmin
PUT/api/v1/allow-list/:idUpdate allow list entryAdmin
DELETE/api/v1/allow-list/:idDelete allow list entryAdmin
GET/api/v1/reports/:typePolicy report (allow or deny)Required
GET/api/v1/threat-feed/statusThreat feed poller statusRequired
POST/api/v1/threat-feed/pollTrigger manual threat feed pollAdmin
GET/api/v1/notifications/settingsGet notification configurationAdmin
PUT/api/v1/notifications/settingsUpdate notification configurationAdmin
GET/healthService health checkPublic
GET/metricsPrometheus metricsPublic
GET/docsSwagger UIPublic