Admin API and management

OSA Proxy provides a dedicated administrative interface (Admin API) for operational tasks: viewing interactive Swagger UI documentation, purging verdict cache entries, monitoring replica status, and centralized configuration management.

By default, the Admin API is disabled and listens on a dedicated network address (default 127.0.0.1:8081). This isolates administrative functions from regular package download traffic.

Enabling the Admin API

To enable the Admin API, configure the admin section in osa-proxy.yml:

admin:
  enabled: true
  address: 127.0.0.1:8081
  write-timeout: 2m
  token-hash: "<sha256-token-hash>"

Configuring the Admin Token

All administrative methods under /api/v1/... are protected by a Bearer token. The configuration stores only the lowercase SHA-256 hash of the token, while the secret token itself is supplied by the client in request headers.

To generate the hash for your chosen secret (for example, my-admin-secret-token):

echo -n "my-admin-secret-token" | sha256sum

Put the resulting hash string into admin.token-hash. To supply it through the OSA_PROXY_ADMIN_TOKEN_HASH environment variable, reference the variable in YAML:

admin:
  token-hash: ${OSA_PROXY_ADMIN_TOKEN_HASH:}
Listener security

The Admin API uses plain HTTP. In production environments, do not expose port 8081 directly to public networks. Use internal networks, Kubernetes NetworkPolicy, or terminate TLS on a trusted reverse proxy with IP restrictions.

Swagger UI and OpenAPI specification

When admin.enabled: true is configured, the following endpoints are available on the admin listener:

  • GET /swagger/ — Swagger UI web interface for interactive API testing. You can click Authorize in the UI and enter your Bearer token;
  • GET /openapi.json — complete OpenAPI 3 specification in JSON format;
  • GET /healthz — health check for the admin listener.

These three endpoints do not require authorization for viewing, but calling API methods within Swagger UI requires entering the Bearer token.

Purging the verdict cache

When a package status changes in CodeScoring or a re-evaluation must be forced, entries can be deleted from the Redis cache without restarting the service.

Include the token in the Authorization: Bearer <token> header:

Purging specific PURLs

The DELETE /api/v1/cache/purls endpoint purges verdicts for specified Package URLs (PURLs):

curl -X DELETE http://127.0.0.1:8081/api/v1/cache/purls \
  -H "Authorization: Bearer my-admin-secret-token" \
  -H "Content-Type: application/json" \
  -d '{
    "purls": [
      "pkg:npm/lodash@4.17.21",
      "pkg:pypi/requests@2.31.0"
    ]
  }'

Example successful response:

{
  "deleted": 2
}

Purging by package type and name

The DELETE /api/v1/cache/packages/{packageType} endpoint purges cache entries for an entire ecosystem or specific package:

curl -X DELETE "http://127.0.0.1:8081/api/v1/cache/packages/npm?packageName=lodash" \
  -H "Authorization: Bearer my-admin-secret-token"

Filtering by repositoryName and repositoryManagerUrl query parameters is also supported for targeted cache invalidation in Artifactory or Nexus contexts (both parameters must be provided together).

Monitoring status and routes

The Admin API allows checking the current replica status and active repositories:

Service status

GET /api/v1/status returns the configuration store state, replica fleet status, and active revision number:

curl -s http://127.0.0.1:8081/api/v1/status \
  -H "Authorization: Bearer my-admin-secret-token"

List of active repositories

GET /api/v1/runtime/repositories returns all routes currently served by this OSA Proxy instance (including static routes from YAML and dynamic routes discovered from Artifactory or Nexus).

Supported query filters:

  • source — filter by route source (yaml, managed, artifactory, nexus);
  • package_type — package ecosystem (npm, maven, pypi, docker, etc.);
  • state — route lifecycle state (desired, active, observed, skipped, unsupported, conflicting, failed, stale, inactive);
  • text — substring search across repository name and upstream URL.
curl -s "http://127.0.0.1:8081/api/v1/runtime/repositories?package_type=npm&state=active" \
  -H "Authorization: Bearer my-admin-secret-token"

Centralized configuration store (Configuration Store)

By default, OSA Proxy reads its settings from the local osa-proxy.yml file. When you need to modify repository settings, webhooks, or CodeScoring behavior dynamically without restarting pods, you can enable the centralized Redis-backed configuration store.

Configuring Configuration Store

configuration-store:
  enabled: true
  backend: redis
  deployment-identity: "production-cluster"
  replica-identity: "osa-proxy-1"
  accept-unsafe-durability: false
  poll-interval: 30s
  operation-timeout: 5s
  history-limit: 20
  redis:
    address: redis:6379
    password: ${CONFIGURATION_STORE_REDIS_PASSWORD:}
    db: 1

If the redis block inside configuration-store is omitted, the service reuses the connection settings from cache.redis. If needed, redis-db: 1 can be specified to use a dedicated database in the same Redis instance.

replica-identity identifies heartbeat and lease records. If omitted, OSA Proxy uses the hostname and falls back to a generated process identity. The Helm chart sets it to the pod name through OSA_PROXY_REPLICA_IDENTITY.

Redis durability requirements (

accept-unsafe-durability) On startup, OSA Proxy validates that Redis is configured for persistent, durable storage: maxmemory-policy must be noeviction, and persistence must be enabled (appendonly yes or RDB snapshots via save). If Redis fails these checks, the service exits with a durability error. To allow starting with an unsafe Redis configuration (e.g. in test environments), set accept-unsafe-durability: true.

On first startup with an empty store, OSA Proxy automatically seeds revision 1 from the local osa-proxy.yml. After that, the store becomes the authoritative source of truth.

Reading and modifying settings via API

  • GET /api/v1/configuration — get the complete desired configuration document (in JSON format) with an aggregate ETag header (format "revision-<N>:sha256:...");
  • /api/v1/configuration/repositories/{package_type} — repositories for the specified package type (npm, maven, ivy, nuget, pypi, composer, ruby, cocoapods, swift, conan, go, hex, r, debian, alpine, rpm, docker);
  • /api/v1/configuration/codescoring — CodeScoring behavior settings (work mode, blocking, messages);
  • /api/v1/configuration/layouts — repository path layouts;
  • /api/v1/configuration/discovery/artifactory and /discovery/nexus — automatic discovery settings;
  • /api/v1/configuration/webhooks — webhook subscriptions (see Webhook configuration).

Safe mutations with ETag

All modifying operations require an If-Match header. This prevents concurrent administrators or scripts from accidentally overwriting each other's changes:

  1. Perform a GET request for the desired section and copy the ETag response header:

    curl -i http://127.0.0.1:8081/api/v1/configuration/codescoring \
      -H "Authorization: Bearer my-admin-secret-token"
  2. Send a PUT request with the updated body, passing the exact ETag in the If-Match header:

    curl -X PUT http://127.0.0.1:8081/api/v1/configuration/codescoring \
      -H "Authorization: Bearer my-admin-secret-token" \
      -H "Content-Type: application/json" \
      -H 'If-Match: "section-codescoring-1:sha256:abc..."' \
      -d '{
        "enable_status_line": true,
        "work_mode": "strict_wait",
        "osa_proxy_url": "https://osa-proxy.example.com",
        "block_on_codescoring_errors": true,
        "stage": "proxy",
        "block_status_code": 403,
        "block_message": "Component blocked by policy",
        "append_block_url_to_message": true
      }'

If the section was modified in the meantime, the server returns 409 Conflict. When this occurs, re-fetch the section, inspect the current state, and retry the update.

Revision history and rollback

Every change creates a new revision. You can inspect history and immediately roll back when necessary:

  • GET /api/v1/configuration/revisions — list stored revisions;

  • GET /api/v1/configuration/revisions/{revision} — view a specific stored revision;

  • POST /api/v1/configuration/revisions/{revision}/rollback — roll back to a specific revision. This request requires the If-Match header containing the current aggregate configuration ETag (from GET /api/v1/configuration):

    curl -X POST http://127.0.0.1:8081/api/v1/configuration/revisions/2/rollback \
      -H "Authorization: Bearer my-admin-secret-token" \
      -H 'If-Match: "revision-3:sha256:..."'
  • GET /api/v1/configuration/export — export the complete current configuration as YAML (secrets are replaced with environment variable references). This file can be used as a seed osa-proxy.yml.

Was this page helpful?