License configuration

Configure your StoatFlow license key for local development and CI/CD — environment variables, system properties, key files, and application.yaml.

StoatFlow validates a license at startup (and re-checks it on a periodic heartbeat). You give it two things: your license key and — for production — an environment label. This page covers every way to provide them, for local development and CI/CD.

The license key

Your key is the signed string from your onboarding email — it starts with key/. The runtime resolves it by looking for an explicit key first, then a key file — and within each, an environment variable beats a system property (which is what an application.yaml value becomes):

  1. An explicit keySTOATFLOW_LICENSE_KEY (environment variable), else the stoatflow.license.key system property (which application.yaml's stoatflow.license.key feeds).
  2. A key fileSTOATFLOW_LICENSE_FILE (environment variable), else the stoatflow.license.file system property (fed by application.yaml's stoatflow.license.file), else the default ~/.stoatflow/license.key.

So an explicit key always wins over a key file, regardless of where each came from.

application.yaml values are applied below environment variables and -D system properties — so an env var always wins over YAML. This lets you commit a YAML default and override it per environment without touching the file.

Pick whichever fits — by source:

# Highest precedence. Good for containers, CI, and one-off local runs.
export STOATFLOW_LICENSE_KEY="key/...your key from the onboarding email..."

The environment label

The environment is a label for the deployment a license seat is bound to — e.g. prod, prod-eu-west, staging, dev. StoatFlow derives a machine fingerprint from it:

fingerprint = SHA-256(application-id || environment)

So the same application-id + the same environment is one seat; distinct environments are distinct seats. Set it with STOATFLOW_LICENSE_ENVIRONMENT, the stoatflow.license.environment system property, or stoatflow.license.environment in application.yaml.

  • Local development (Trial / Developer tiers): if you don't set it, the environment defaults to <your-username>-<hostname> — one seat per developer machine, no configuration needed.
  • Production: the Production tier requires an explicit environment — startup fails if it has to auto-generate one. Set it per deployment (prod, prod-eu-west, …) so each gets its own node-locked seat.

Local development

The simplest local setup is the key file — write it once and every StoatFlow app you run locally is licensed, with no env vars and an auto-derived per-machine environment:

mkdir -p ~/.stoatflow
printf '%s' 'key/...your developer key...' > ~/.stoatflow/license.key
chmod 600 ~/.stoatflow/license.key

Prefer per-run configuration? Export the key (and optionally the environment) in your shell:

export STOATFLOW_LICENSE_KEY="key/...your developer key..."
# Optional — defaults to <username>-<hostname> if unset:
export STOATFLOW_LICENSE_ENVIRONMENT="dev-$(whoami)"

CI/CD

Use your CI/CD-tier key (it carries a higher machine cap suited to short-lived build agents). Store it as an encrypted secret — never in the repo.

On GitHub Actions, StoatFlow auto-detects the run and sets the environment to cicd-<run id> for you, so each run gets a fresh, ephemeral seat — you only need to provide the key:

# .github/workflows/your-workflow.yml
jobs:
  integration-test:
    runs-on: ubuntu-latest
    env:
      STOATFLOW_LICENSE_KEY: ${{ secrets.STOATFLOW_CI_LICENSE }}
      # Optional — auto-derived as cicd-${GITHUB_RUN_ID} on GitHub Actions:
      # STOATFLOW_LICENSE_ENVIRONMENT: cicd-${{ github.run_id }}
    steps:
      - uses: actions/checkout@v4
      # ... build + run StoatFlow tests ...

On other CI systems (GitLab CI, Jenkins, …) there's no auto-detection — set the environment explicitly to something unique-per-run so concurrent builds don't contend for one seat:

export STOATFLOW_LICENSE_KEY="$STOATFLOW_CI_LICENSE"
export STOATFLOW_LICENSE_ENVIRONMENT="cicd-${CI_PIPELINE_ID:-$(date +%s)}"

All license settings

Every setting, with its environment variable, system property, and application.yaml key (under stoatflow.license). Environment variable wins over system property wins over YAML.

application.yaml (stoatflow.license.*)Environment variableSystem propertyDefaultPurpose
keySTOATFLOW_LICENSE_KEYstoatflow.license.keyThe signed license key (key/…).
fileSTOATFLOW_LICENSE_FILEstoatflow.license.file~/.stoatflow/license.keyPath to a file containing the key.
environmentSTOATFLOW_LICENSE_ENVIRONMENTstoatflow.license.environment<username>-<hostname> (auto)Seat label; required for Production.
cache-dirSTOATFLOW_LICENSE_CACHE_DIRstoatflow.license.cache-dir~/.stoatflow/license-cache/Where the offline-grace cache is stored.
verbose-bannerSTOATFLOW_LICENSE_VERBOSE_BANNERstoatflow.license.verbose-bannerfalseLog a detailed license banner at startup.
Heartbeat cadence and offline-grace are set by your license tier, not by configuration. They govern how quickly a license change takes effect and how long the engine tolerates a Keygen outage — so they're tuned per tier rather than left to each deployment. If your environment needs a longer offline-grace window (intermittent connectivity, restricted egress), talk to us and we'll set it on your license.

Troubleshooting

  • Startup fails: license missing / invalid / expired / revoked. StoatFlow hard-fails fast rather than running unlicensed. Check the key is set (precedence above) and current.
  • license key file has insecure permissions. The key file must be owner-only — chmod 600 ~/.stoatflow/license.key.
  • Production refuses to start without an environment. Set STOATFLOW_LICENSE_ENVIRONMENT (or stoatflow.license.environment) explicitly — Production won't auto-generate one.
  • Brief Keygen outage. The runtime keeps serving from its offline cache for the grace window, then fails on the next check. Normal restarts within the window are fine.
  • Lost your key or token? We re-issue rather than retrieve — reply to your onboarding email and we'll rotate it.

Next steps