OSS Risk Radar

How it's set up

API reference

The Go API is the only public surface — the web app is just a client of it. Everything is JSON over /api/v1 with no auth in the reference deployment; access is expected to be network-scoped. Scoring is asynchronous: create an analysis, then poll it.

Analyses

Create an analysis and read it back. Creation is asynchronous — you get a job to poll.

POST/api/v1/analyses

Submit a repository (or demo/upload) and start scoring. Returns the analysis + a job.

GET/api/v1/analyses

List previous analyses.

GET/api/v1/analyses/{analysisId}

Fetch one analysis with its summary, dependencies, and status.

GET/api/v1/analyses/{analysisId}/dependencies

List the scored repositories for an analysis.

Dependencies & jobs

Drill into a single scored repository, or poll the background job that produced it.

GET/api/v1/dependencies/{dependencyId}

One scored repository: risk profile, evidence, raw signals, features.

GET/api/v1/jobs/{jobId}

Poll a scoring job's status (pending / running / completed / failed).

Training & evaluation

Read-only views of the promoted model and the dataset behind it — this is what the docs' evaluation pages render.

GET/api/v1/training/dataset

Summary of the labeled dataset (size, class balance, coverage).

GET/api/v1/training/effects

Ablation / feature-effect results, e.g. the bot-filter comparison.

GET/api/v1/training/runs

List training runs with held-out metrics.

GET/api/v1/training/runs/latest

The currently deployed run and its metrics.

Operational

Liveness and readiness, unversioned. Ready reports whether the scoring service is reachable.

GET/health

Liveness — the process is up.

GET/ready

Readiness — downstream scoring is reachable, else degraded.

The create → poll flow

Creating an analysis kicks off a background job and returns straight away with status: "pending". Poll the analysis (or the job) until it is completed, then read the dependencies for the risk profile. By default an identical recent submission is reused (HTTP 200 with reusedExistingAnalysis: true); send "force": true to force a fresh run.

request
POST /api/v1/analyses
Content-Type: application/json

{
  "submission": {
    "kind": "repository_url",
    "repositoryUrl": "https://github.com/owner/repo"
  }
}
response
HTTP/1.1 201 Created

{
  "analysis": { "id": "an_...", "status": "pending", ... },
  "job":      { "id": "job_...", "status": "pending", ... },
  "reusedExistingAnalysis": false
}
poll then read
# poll the analysis until status is "completed"
curl -s http://localhost:8080/api/v1/analyses/an_... | jq '.analysis.status'

# then read the scored repository
curl -s http://localhost:8080/api/v1/analyses/an_.../dependencies \
  | jq '.dependencies[0].riskProfile'

Conventions

  • Submission kinds: repository_url, demo, and upload — each repository is scored on its own (see How scoring a repo works).
  • Errors come back as { "error": "..." } with a matching HTTP status (400 bad payload, 404 unknown id, 500 internal).
  • Base URL is configurable; it defaults to http://localhost:8080 locally, and the web app proxies it at /api/v1.

For how these pieces fit together, see the system architecture.