ATT&CK Workbench REST API Configuration Guide

May 7, 2026 · View on GitHub

This guide explains how to configure the ATT&CK Workbench REST API using environment variables, JSON configuration files, or a combination of both.

Table of Contents


Configuration System Overview

The REST API uses Convict, a configuration management library. All configuration is defined in app/config/config.js with sensible defaults. You only need to override values specific to your environment.


Configuration Methods

Environment Variables

Environment variables are the recommended method for configuring the REST API in containerized deployments and for simple configurations.

A template.env file is included in the repository for you to make use of this option.

JSON Configuration File

JSON configuration files are recommended for complex configurations, especially when defining service accounts or OIDC clients.

Setting up JSON configuration:

  1. Create a configuration file (e.g., config.json):

    {
      "server": {
        "port": 3000,
        "corsAllowedOrigins": ["https://workbench.example.com", "https://staging.example.com"]
      },
      "database": {
        "url": "mongodb://localhost:27017/attack-workspace"
      },
      "userAuthn": {
        "mechanism": "oidc",
        "oidc": {
          "issuerUrl": "https://auth.example.com/realms/workbench",
          "clientId": "attack-workbench-rest-api",
          "clientSecret": "your-client-secret",
          "redirectOrigin": "https://workbench.example.com"
        }
      },
      "serviceAuthn": {
        "basicApikey": {
          "enable": true,
          "serviceAccounts": [
            {
              "name": "navigator",
              "apikey": "your-navigator-apikey",
              "serviceRole": "read-only"
            },
            {
              "name": "collection-manager",
              "apikey": "your-collection-manager-apikey",
              "serviceRole": "collection-manager"
            }
          ]
        }
      }
    }
    
  2. Reference the file via environment variable:

    export JSON_CONFIG_PATH=/path/to/config.json
    npm start
    

    Or in .env:

    JSON_CONFIG_PATH=/path/to/config.json
    

Configuration Precedence

When both environment variables and JSON configuration are used:

  1. Environment variables are loaded first with their defaults
  2. JSON configuration file (if specified) is loaded second and overrides environment variables
  3. Validation occurs after all configuration is loaded

Example:

# .env file
PORT=3000
DATABASE_URL=mongodb://localhost:27017/attack-workspace
JSON_CONFIG_PATH=./config.json
// config.json
{
  "server": {
    "port": 8080
  }
}

Result: Port will be 8080 (JSON overrides environment variable)


Configuration Options

Server

Configuration for the HTTP server.

OptionEnvironment VariableJSON PathTypeDefaultDescription
PortPORTserver.portinteger3000HTTP server port
CORS Allowed OriginsCORS_ALLOWED_ORIGINSserver.corsAllowedOriginsdomains*Allowed origins for CORS. Use * for all, disable to disable CORS, or comma-separated list of origins

CORS Allowed Origins accepts:

  • * - Allow any origin (not recommended for production)
  • disable - Disable CORS entirely
  • Comma-separated list of origins (with protocol):
    • https://workbench.example.com
    • http://localhost:4200,https://workbench.example.com
  • Supports localhost, private IPs (10.x, 172.16-31.x, 192.168.x), and FQDNs

Examples:

# Environment variable
CORS_ALLOWED_ORIGINS=https://workbench.example.com,https://staging.example.com
// JSON
{
  "server": {
    "corsAllowedOrigins": ["https://workbench.example.com", "https://staging.example.com"]
  }
}

Database

MongoDB database configuration.

OptionEnvironment VariableJSON PathTypeDefaultDescription
URLDATABASE_URLdatabase.urlstring(empty)MongoDB connection string (REQUIRED)
Auto-migrateWB_REST_DATABASE_MIGRATION_ENABLEdatabase.migration.enablebooleantrueRun migrations automatically on startup

Examples:

# Local MongoDB
DATABASE_URL=mongodb://localhost:27017/attack-workspace

# Docker Compose
DATABASE_URL=mongodb://attack-workbench-database/attack-workspace

Migration Notes:

  • When database.migration.enable is true, migrations run automatically at startup
  • Set to false if you manage migrations separately (e.g., in a Kubernetes init container)
  • Migrations are idempotent and safe to run multiple times
  • Automation-enabled migrations may also write durable audit records to automationRuns and automationRunItems; see Automation Run Audit Trail

Application

General application settings.

OptionEnvironment VariableJSON PathTypeDefaultDescription
Name(none)app.namestringattack-workbench-rest-apiApplication name
EnvironmentNODE_ENVapp.envstringdevelopmentEnvironment name (development, production, test)
Version(none)app.versionstring(from package.json)Application version
ATT&CK Spec Version(none)app.attackSpecVersionstring(from package.json)ATT&CK specification version

Example:

NODE_ENV=production

Logging

Logging configuration using Winston.

OptionEnvironment VariableJSON PathTypeDefaultDescription
Log LevelLOG_LEVELlogging.logLevelstringinfoConsole log level

Log Levels (from least to most verbose):

  • error - Only errors
  • warn - Warnings and errors
  • http - HTTP requests, warnings, and errors
  • info - General information (recommended for production)
  • verbose - Detailed information
  • debug - Debug messages (recommended for development)

Example:

LOG_LEVEL=debug

Session

Session management for user authentication.

OptionEnvironment VariableJSON PathTypeDefaultDescription
SecretSESSION_SECRETsession.secretstring(generated at startup)Secret used to sign session cookies
Mongo Session SecretMONGOSTORE_CRYPTO_SECRETsession.mongoStoreCryptoSecretstring(generated at startup)Secret to encrypt session data in MongoDB

Important Notes:

  • If not set, a secret is generated randomly at startup
  • Random secrets are regenerated on restart, forcing users to re-login
  • Random secrets cannot be shared across multiple server instances
  • Production: Always set SESSION_SECRET to a fixed, secure value

Generating a secure secret:

node -e "console.log(require('crypto').randomBytes(48).toString('base64'))"

Example:

SESSION_SECRET=your-secure-secret-here
MONGOSTORE_CRYPTO_SECRET=your-secure-secret-here

User Authentication

Configuration for user authentication (how end-users log in).

OptionEnvironment VariableJSON PathTypeDefaultDescription
MechanismAUTHN_MECHANISMuserAuthn.mechanismenumanonymousAuthentication mechanism to use

Mechanism Options:

  • anonymous - No authentication required (development only)
  • oidc - OpenID Connect (recommended for production)

OIDC Configuration

Required when mechanism is set to oidc.

OptionEnvironment VariableJSON PathTypeDefaultDescription
Issuer URLAUTHN_OIDC_ISSUER_URLuserAuthn.oidc.issuerUrlstring(empty)OIDC provider's issuer URL
Client IDAUTHN_OIDC_CLIENT_IDuserAuthn.oidc.clientIdstring(empty)OIDC client identifier
Client SecretAUTHN_OIDC_CLIENT_SECRETuserAuthn.oidc.clientSecretstring(empty)OIDC client secret
Redirect OriginAUTHN_OIDC_REDIRECT_ORIGINuserAuthn.oidc.redirectOriginstringhttp://localhost:3000Base URL for redirect URI

Example:

AUTHN_MECHANISM=oidc
AUTHN_OIDC_ISSUER_URL=https://auth.example.com/realms/workbench
AUTHN_OIDC_CLIENT_ID=attack-workbench-rest-api
AUTHN_OIDC_CLIENT_SECRET=your-client-secret
AUTHN_OIDC_REDIRECT_ORIGIN=https://workbench.example.com

For detailed OIDC setup, see Authentication Documentation.

Service Authentication

Configuration for service-to-service authentication (APIs, automation tools).

The REST API supports three service authentication methods:

  1. OIDC Client Credentials - OAuth2 client credentials flow
  2. Challenge API Key - Token exchange with challenge/response
  3. Basic API Key - Simple API key authentication

All methods support role-based access control with three service roles:

  • read-only - Read-only access to endpoints
  • collection-manager - Read/write access for collection management
  • stix-export - Access to STIX export endpoints

OIDC Client Credentials

Uses OAuth2 Client Credentials flow with JWT validation.

OptionEnvironment VariableJSON PathTypeDefaultDescription
EnableSERVICE_ACCOUNT_OIDC_ENABLEserviceAuthn.oidcClientCredentials.enablebooleanfalseEnable OIDC client credentials authentication
JWKS URIJWKS_URIserviceAuthn.oidcClientCredentials.jwksUristring(empty)JWKS endpoint for IdP public keys
Clients(JSON only)serviceAuthn.oidcClientCredentials.clientsarray[]Array of authorized OIDC clients

Clients Array Schema:

{
  "clientId": "string",      // OIDC client ID
  "serviceRole": "enum"      // Service role (read-only, collection-manager, stix-export)
}

Example:

# .env
SERVICE_ACCOUNT_OIDC_ENABLE=true
JWKS_URI=https://auth.example.com/realms/workbench/protocol/openid-connect/certs
JSON_CONFIG_PATH=./config.json
// config.json
{
  "serviceAuthn": {
    "oidcClientCredentials": {
      "enable": true,
      "clients": [
        {
          "clientId": "collection-manager-service",
          "serviceRole": "collection-manager"
        }
      ]
    }
  }
}

See sample configurations:

Challenge API Key

Token exchange authentication with challenge/response mechanism.

OptionEnvironment VariableJSON PathTypeDefaultDescription
EnableWB_REST_SERVICE_ACCOUNT_CHALLENGE_APIKEY_ENABLEserviceAuthn.challengeApikey.enablebooleanfalseEnable challenge API key authentication
Token Signing SecretWB_REST_TOKEN_SIGNING_SECRETserviceAuthn.challengeApikey.secretstring(generated at startup)Secret used to sign access tokens
Token TimeoutWB_REST_TOKEN_TIMEOUTserviceAuthn.challengeApikey.tokenTimeoutinteger300Access token lifetime in seconds
Service Accounts(JSON only)serviceAuthn.challengeApikey.serviceAccountsarray[]Array of service accounts

Service Accounts Array Schema:

{
  "name": "string",          // Service account name
  "apikey": "string",        // Shared secret (API key)
  "serviceRole": "enum"      // Service role
}

Example:

# .env
WB_REST_SERVICE_ACCOUNT_CHALLENGE_APIKEY_ENABLE=true
WB_REST_TOKEN_SIGNING_SECRET=your-secure-secret
WB_REST_TOKEN_TIMEOUT=600
JSON_CONFIG_PATH=./config.json
// config.json
{
  "serviceAuthn": {
    "challengeApikey": {
      "enable": true,
      "serviceAccounts": [
        {
          "name": "collection-manager",
          "apikey": "your-secure-apikey",
          "serviceRole": "collection-manager"
        }
      ]
    }
  }
}

See sample: test-service-challenge-apikey.json

Basic API Key

Simple API key authentication (no challenge).

OptionEnvironment VariableJSON PathTypeDefaultDescription
EnableWB_REST_SERVICE_ACCOUNT_BASIC_APIKEY_ENABLEserviceAuthn.basicApikey.enablebooleanfalseEnable basic API key authentication
Service Accounts(JSON only)serviceAuthn.basicApikey.serviceAccountsarray[]Array of service accounts

Service Accounts Array Schema:

{
  "name": "string",          // Service account name
  "apikey": "string",        // API key
  "serviceRole": "enum"      // Service role
}

Example:

# .env
WB_REST_SERVICE_ACCOUNT_BASIC_APIKEY_ENABLE=true
JSON_CONFIG_PATH=./config.json
// config.json
{
  "serviceAuthn": {
    "basicApikey": {
      "enable": true,
      "serviceAccounts": [
        {
          "name": "navigator",
          "apikey": "your-navigator-apikey",
          "serviceRole": "read-only"
        }
      ]
    }
  }
}

See sample: navigator-basic-apikey.json

Multiple Service Authentication Methods

You can enable multiple service authentication methods simultaneously:

{
  "serviceAuthn": {
    "oidcClientCredentials": {
      "enable": true,
      "clients": [
        {
          "clientId": "automated-collection-manager",
          "serviceRole": "collection-manager"
        }
      ]
    },
    "challengeApikey": {
      "enable": true,
      "serviceAccounts": [
        {
          "name": "legacy-service",
          "apikey": "legacy-apikey",
          "serviceRole": "read-only"
        }
      ]
    },
    "basicApikey": {
      "enable": true,
      "serviceAccounts": [
        {
          "name": "navigator",
          "apikey": "navigator-apikey",
          "serviceRole": "read-only"
        }
      ]
    }
  }
}

See sample: multiple-apikey-services.json

Scheduler

Background job scheduler configuration.

OptionEnvironment VariableJSON PathTypeDefaultDescription
EnableENABLE_SCHEDULERscheduler.enableSchedulerbooleantrueEnable background job scheduler
Check IntervalCHECK_WORKBENCH_INTERVALscheduler.checkWorkbenchIntervalinteger10Scheduler check interval in seconds

Scheduler Functions:

  • Checks for collection index updates
  • Downloads collection bundles from remote URLs
  • Processes subscription update policies

Example:

ENABLE_SCHEDULER=true
CHECK_WORKBENCH_INTERVAL=30

Validation

Configuration for ATT&CK Data Model (ADM) request validation and the scheduled re-validation task.

OptionEnvironment VariableJSON PathTypeDefaultDescription
Validate RequestsVALIDATE_WITH_ADM_SCHEMASvalidateRequests.withAttackDataModelbooleanfalseRun incoming POST/PUT bodies through the ADM schemas before persisting
Re-validate CronVALIDATE_OBJECTS_CRONscheduler.validateObjectsCronstring0 3 * * *Cron pattern for the background task that refreshes workspace.validation on every document
ADM Log LevelADM_LOG_LEVEL(env only)enumwarnVerbosity of the ADM library's internal logger

VALIDATE_WITH_ADM_SCHEMAS

When enabled, every POST and PUT validates the composed STIX payload against the ADM schemas before saving. Failed validations cause the request to throw with an HTTP error and the document is not persisted. When disabled, the write pipeline does not gate on ADM compliance and downstream tools are responsible for detecting non-compliant content.

This setting does not affect the legacy OpenAPI request validation (VALIDATE_WITH_LEGACY_SCHEMAS), which can be enabled or disabled independently.

VALIDATE_OBJECTS_CRON

The Workbench scheduler periodically re-validates every SDO and SRO in the database against the current ADM and refreshes each document's workspace.validation field. This combats concept drift: documents that passed validation under an older ADM version may become non-compliant after a Workbench upgrade.

The cron pattern follows standard 5-field syntax (minute hour day-of-month month day-of-week). The default 0 3 * * * runs the task daily at 3:00 AM. The task is skipped entirely if the global scheduler is disabled (ENABLE_SCHEDULER=false).

For the lifecycle of workspace.validation itself, see Stateful Validation Tracking.

ADM_LOG_LEVEL

Read by the @mitre-attack/attack-data-model library directly — not a Convict-managed setting and not configurable via JSON_CONFIG_PATH. It controls the verbosity of the ADM library's own logger, which is independent of the Workbench LOG_LEVEL.

This was introduced primarily to suppress the deprecation warning that the ADM emits for every relationship in the database during a re-validation run. Setting ADM_LOG_LEVEL=error (or silent) keeps the scheduled task quiet without affecting Workbench's own logs.

LevelDescription
debugVerbose diagnostic output
infoInformational status messages (data retrieval, parse counts, etc.)
warnValidation issues in relaxed mode and deprecation warnings
errorErrors only
silentDisables all output

Levels are inclusive: setting info enables info, warn, and error. The default is warn.

Examples:

# Enable ADM-based request validation
VALIDATE_WITH_ADM_SCHEMAS=true

# Run re-validation hourly instead of daily at 3 AM
VALIDATE_OBJECTS_CRON=0 * * * *

# Suppress noisy ADM deprecation warnings during scheduler runs
ADM_LOG_LEVEL=error

Collection Indexes

Configuration for ATT&CK collection index subscriptions.

OptionEnvironment VariableJSON PathTypeDefaultDescription
Default IntervalDEFAULT_INTERVALcollectionIndex.defaultIntervalinteger300Default update check interval in seconds

Notes:

  • Only applies to new collection indexes added after configuration change
  • Does not affect existing collection indexes (they retain their configured interval)

Configuration Files

Paths to additional configuration and data files.

OptionEnvironment VariableJSON PathTypeDefaultDescription
JSON Config PathJSON_CONFIG_PATHconfigurationFiles.jsonConfigFilestring(empty)Path to JSON configuration file
Allowed Values PathALLOWED_VALUES_PATHconfigurationFiles.allowedValuesstring./app/config/allowed-values.jsonPath to allowed values configuration
Static Marking Definitions PathWB_REST_STATIC_MARKING_DEFS_PATHconfigurationFiles.staticMarkingDefinitionsPathstring./app/lib/default-static-marking-definitions/Directory containing static marking definitions

Allowed Values:

The allowed values file defines valid enum values for STIX object properties (platforms, permissions, etc.). See app/config/allowed-values.json for the schema.

Static Marking Definitions:

Directory containing JSON files with STIX marking definitions that are automatically loaded into the system on startup.

ATT&CK Specific

ATT&CK-specific configuration values.

OptionEnvironment VariableJSON PathTypeDefaultDescription
Attack Source Names(JSON only)attackSourceNamesarraySee belowValid source_name values in ATT&CK external_references
Domain to Kill Chain Map(JSON only)domainToKillChainMapobjectSee belowMaps domain names to kill chain phase names

Default Attack Source Names:

["mitre-attack", "mitre-mobile-attack", "mobile-attack", "mitre-ics-attack"]

Default Domain to Kill Chain Map:

{
  "enterprise-attack": "mitre-attack",
  "mobile-attack": "mitre-mobile-attack",
  "ics-attack": "mitre-ics-attack"
}

Additional Resources