# Runtime configuration reference

## Contents

- [Scope and evidence](#scope-and-evidence)
- [Secret-handling rules](#secret-handling-rules)
- [Local runner parameters](#local-runner-parameters)
- [Local environment template](#local-environment-template)
- [Optional local config file](#optional-local-config-file)
- [Run the local scenario](#run-the-local-scenario)
- [GitHub Actions workflow selection](#github-actions-workflow-selection)
- [GitHub Actions input matrix](#github-actions-input-matrix)
- [Current workflow constraints](#current-workflow-constraints)
- [Required secret-backed workflow contract](#required-secret-backed-workflow-contract)
- [Dispatch in the GitHub UI](#dispatch-in-the-github-ui)
- [Dispatch with GitHub CLI](#dispatch-with-github-cli)
- [Dispatch with the REST API](#dispatch-with-the-rest-api)
- [Verify a dispatched run](#verify-a-dispatched-run)

## Scope and evidence

This reference combines:

- current `tidb-management-service` workflow input definitions and `OPEN_API_DEDICATED_*` mappings;
- current Go runner validation and setup behavior;
- the structure of an operational automation host whose provider-specific shell scripts dispatch GitHub workflows through the REST API;
- a wrapper that executes one trigger script, captures stdout/stderr in permission-restricted logs, updates a latest log, and returns the trigger script's exit code.

Only parameter names, control flow, and data shapes are retained. Do not add automation hostnames, usernames, paths, repository tokens, API credentials, tenant/project IDs, DSNs, account details, storage tokens, or environment-specific values to this skill.

Runner and workflow facts were inspected at [`tidbcloud/tidb-management-service@ff5c78ac9`](https://github.com/tidbcloud/tidb-management-service/tree/ff5c78ac952849735b14a93ecabcceec4933ea33) on 2026-07-15. Mutable `main` links are for freshness checks only; use the pinned revision for reproducible evidence.

## Secret-handling rules

- Keep all examples placeholder-only.
- Store local secrets in an approved credential manager or protected process environment, not in the repository.
- Store GitHub dispatch credentials as a GitHub App/fine-grained token with the minimum required Actions write permission. Do not embed the token in a shell script.
- Treat the runner API key, alternate auth-role keys, account password/token, DSNs, provider credentials, and storage tokens as secrets even when an existing script or workflow contains literals.
- Do not enable `set -x` in trigger or runner scripts. The automation wrapper logs combined stdout/stderr.
- Do not print the workflow payload, auth JSON, environment, or request headers.
- Make secret directories mode `0700` and secret/log files mode `0600`; use `umask 077` in automation scripts.
- Verify local secret files are ignored before use. Remove copied YAML and unset exported secrets after the run.
- Prefer GitHub repository/environment secrets over `workflow_dispatch` inputs for sensitive values. Inputs are operational metadata and are not a secret store.
- The current global workflows require an `auth` string input. Treat this as compatibility behavior, not a safe long-term secret-delivery design; prefer changing the workflow to read authentication material from GitHub environment secrets.

## Local runner parameters

Use environment variables for secrets and frequently changed values. The environment overrides the optional Viper config file.

| Runner key | Required | Safe value shape and source |
|---|---:|---|
| `OPEN_API_DEDICATED_ENV` | Yes | `<environment>` selected for the test account. |
| `OPEN_API_DEDICATED_HOST` | HTTP cases | `<api-host-without-scheme>`; match the API tier and environment. |
| `OPEN_API_DEDICATED_API_KEY` | Global/digest cases | `<public-key>:<private-key>` from an approved secret source. |
| `OPEN_API_DEDICATED_AUTH_ROLE` | Alternate-role cases | JSON map: `{"<role-name>":"<public-key>:<private-key>"}`. |
| `OPEN_API_DEDICATED_PROJECT_ID` | Yes for the current suite | `<project-id>` belonging to the test tenant/environment. |
| `OPEN_API_DEDICATED_TENANT_ID` | Scenario-dependent, normally yes | `<tenant-id>` belonging to the same environment. |
| `OPEN_API_DEDICATED_CLOUD_PROVIDER` | Yes | `<provider>` matching the YAML and installed CLI. |
| `OPEN_API_DEDICATED_REGION` | Yes | `<region>` valid for the selected provider and scenario. |
| `OPEN_API_DEDICATED_DB_API_TESTER_DSN` | Current full replay | `<approved-tester-dsn>` from a protected source. Setup opens this connection even for regional hosts and when result inserts are disabled. |
| `OPEN_API_DEDICATED_DB_API_GENERATOR_DSN` | Current full replay | `<approved-generator-dsn>` from a protected source. Setup opens this connection even when reading embedded YAML. |
| `OPEN_API_DEDICATED_READ_CASE_FROM_FS` | Committed YAML replay | `true`. |
| `OPEN_API_DEDICATED_SCENARIO_YAML` | Yes | Exact basename under `scenario_testcases/`, after copying it into runner testdata. |
| `OPEN_API_DEDICATED_SAVE_RESULT_TO_DB` | Recommended explicit | `false` for ad hoc validation unless persistence is required. |
| `OPEN_API_DEDICATED_SKIP_TEAR_DOWN` | Recommended explicit | `false`; do not disable cleanup to hide a failing teardown. |
| `OPEN_API_DEDICATED_ACCOUNT_TOKEN` | Strongly recommended locally | Protected bearer token. Supplying it avoids the runner's unconditional browser-login attempt when this value is empty. |
| `OPEN_API_DEDICATED_LOGIN_URL` | Required when account token is empty | `<login-url>` matching the account environment. |
| `OPEN_API_DEDICATED_ACCOUNT_EMAIL` | Required when account token is empty | `<account-email>` from a protected source. |
| `OPEN_API_DEDICATED_ACCOUNT_PWD` | Required when account token is empty | `<account-password>` from a protected source. |
| `OPEN_API_DEDICATED_AWS_PROFILE` | AWS command cases when profile-based auth is used | `<aws-profile-name>` already authenticated outside the repository. |
| `OPEN_API_DEDICATED_AZURE_ACCOUNT_SAS_TOKEN` | Azure case-dependent | Protected account-level token only when the selected YAML consumes its placeholder. |
| `OPEN_API_DEDICATED_AZURE_BLOB_SAS_TOKEN` | Azure case-dependent | Protected blob-level token only when the selected YAML consumes its placeholder. |
| `IAM_AWS_KEY_ID`, `IAM_AWS_KEY_SECRET` | AWS placeholder-dependent | Protected process variables read directly by the runner, without the `OPEN_API_DEDICATED_` prefix. |
| `IAM_ALI_KEY_ID`, `IAM_ALI_KEY_SECRET` | AliCloud placeholder-dependent | Protected process variables read directly by the runner, without the `OPEN_API_DEDICATED_` prefix. |
| Other provider CLI variables | Command case-dependent | Supply only the standard credentials consumed by the CLI commands in the selected YAML. |

The current suite opens both database connections during setup even when reading embedded YAML and setting `SAVE_RESULT_TO_DB=false`. A full local replay therefore needs reachable tester and generator DSNs. Static validation and compile-only validation do not.

## Local environment template

Keep selectors in a reviewed local shell fragment, but inject every secret from the process environment or an approved secret manager. Do not put literal secrets in this file.

```sh
umask 077

: "${TIDB_CLOUD_API_KEY:?load from approved secret source}"
: "${API_TESTER_DSN:?load from approved secret source}"
: "${API_GENERATOR_DSN:?load from approved secret source}"

export OPEN_API_DEDICATED_ENV='<environment>'
export OPEN_API_DEDICATED_HOST='<api-host-without-scheme>'
export OPEN_API_DEDICATED_API_KEY="${TIDB_CLOUD_API_KEY}"
export OPEN_API_DEDICATED_PROJECT_ID='<project-id>'
export OPEN_API_DEDICATED_TENANT_ID='<tenant-id>'
export OPEN_API_DEDICATED_CLOUD_PROVIDER='<provider>'
export OPEN_API_DEDICATED_REGION='<region>'
export OPEN_API_DEDICATED_DB_API_TESTER_DSN="${API_TESTER_DSN}"
export OPEN_API_DEDICATED_DB_API_GENERATOR_DSN="${API_GENERATOR_DSN}"
export OPEN_API_DEDICATED_READ_CASE_FROM_FS=true
export OPEN_API_DEDICATED_SCENARIO_YAML='<scenario-file.yaml>'
export OPEN_API_DEDICATED_SAVE_RESULT_TO_DB=false
export OPEN_API_DEDICATED_SKIP_TEAR_DOWN=false

if [ -n "${TIDB_CLOUD_ACCOUNT_TOKEN:-}" ]; then
  export OPEN_API_DEDICATED_ACCOUNT_TOKEN="${TIDB_CLOUD_ACCOUNT_TOKEN}"
else
  : "${TIDB_CLOUD_ACCOUNT_EMAIL:?load from approved secret source}"
  : "${TIDB_CLOUD_ACCOUNT_PWD:?load from approved secret source}"
  export OPEN_API_DEDICATED_LOGIN_URL='<login-url>'
  export OPEN_API_DEDICATED_ACCOUNT_EMAIL="${TIDB_CLOUD_ACCOUNT_EMAIL}"
  export OPEN_API_DEDICATED_ACCOUNT_PWD="${TIDB_CLOUD_ACCOUNT_PWD}"
fi
```

Add only the optional auth/provider variables required by the selected YAML. Confirm all selectors refer to the same environment before executing.

## Optional local config file

Use a config file only for non-secret selectors. Environment variables override these values.

```yaml
env: "<environment>"
host: "<api-host-without-scheme>"
project_id: "<project-id>"
tenant_id: "<tenant-id>"
cloud_provider: "<provider>"
region: "<region>"
read_case_from_fs: true
scenario_yaml: "<scenario-file.yaml>"
save_result_to_db: false
skip_tear_down: false
```

Keep API keys, role auth, account credentials, DSNs, provider credentials, and storage tokens in the environment. Place the config outside the repository or verify it is ignored and mode `0600`.

When invoking the package directly, the runner accepts `-config-name` and `-config-path` test arguments. The standard GHA/Make path uses environment variables and is the preferred reproduction path.

## Run the local scenario

1. Run the static checker and explicitly follow `skills/review-scenario-yaml/SKILL.md` first.
2. Copy the exact APITestGen YAML into `functional-test/cases/openapidedicated/autogencase/testdata/` before compilation because `go:embed` captures files at build time.
3. Install and authenticate only the provider/SQL CLIs referenced by the scenario.
4. Load the protected environment.
5. From `tidb-management-service/functional-test`, run:

   ```sh
   make GO_TEST_RUN_ARGS='TestScenario' GO_TEST_TESTIFY_METHOD='.*' \
     test-openapidedicated-autogencase
   ```

6. Inspect `e2e-tests.xml`, action logs, saved placeholders, and teardown output.
7. Verify all non-cluster resources were explicitly removed, then delete the copied testdata file and unset secret variables.

## GitHub Actions workflow selection

The inspected automation scripts dispatch these workflow families:

| Scenario family | Workflow source | Auth input |
|---|---|---|
| Essential | [`e2e-openapi-essential-scenario.yaml`](https://github.com/tidbcloud/tidb-management-service/blob/ff5c78ac952849735b14a93ecabcceec4933ea33/.github/workflows/e2e-openapi-essential-scenario.yaml) | Required JSON string. |
| NextGen global | [`e2e-openapi-nextgen-scenario.yaml`](https://github.com/tidbcloud/tidb-management-service/blob/ff5c78ac952849735b14a93ecabcceec4933ea33/.github/workflows/e2e-openapi-nextgen-scenario.yaml) | Required JSON string. |
| NextGen regional | [`e2e-regionalapi-nextgen-scenario.yaml`](https://github.com/tidbcloud/tidb-management-service/blob/ff5c78ac952849735b14a93ecabcceec4933ea33/.github/workflows/e2e-regionalapi-nextgen-scenario.yaml) | Not declared by the workflow. |

Use the other workflow links in [authoring-and-validation.md](authoring-and-validation.md) for Dedicated, BYOC, or Essential V2 cases.

The REST payload's top-level `ref` selects the branch or tag of `tidb-management-service` that contains the workflow. It does not select the APITestGen branch. The three workflows above currently fetch scenario YAML from APITestGen `main`, so they cannot see an unmerged APITestGen branch without a reviewed workflow change.

## GitHub Actions input matrix

| Input | Essential | NextGen global | NextGen regional | How to fill |
|---|---:|---:|---:|---|
| `environment` | Yes | Yes | Yes | `<environment>` matching credentials, host, IDs, provider, and region. |
| `cloud_provider` | Yes | Yes | Yes | `<provider>`; also selects the matching scenario list input. |
| `region` | Yes | Yes | Yes | `<region>` valid for the provider and scenario. |
| `tenant_id` | Yes | Yes | Yes | `<tenant-id>` from an approved configuration source. |
| `project_id` | No input | Optional | No input | Set only for NextGen global when the case must target an explicit project. |
| `host` | No input | No input | Optional | Omit to use the workflow's environment mapping; override only with reviewed evidence. |
| `auth` | Required | Required | No input | JSON string described below; build it in memory from protected values. |
| `scenario_yamls_<provider>` | Yes | Yes | Yes | Exact APITestGen basenames, comma-separated without spaces. Pass only the selected provider field. |
| `config` | Optional | Optional | No declared input | Explicit safe JSON is recommended for Essential/global. Regional hardcodes filesystem loading and disables result inserts. |

Although several workflow fields define defaults, pass environment, provider, region, tenant, and the exact scenario list explicitly. This prevents an automation script from silently using a default intended for another run.

## Current workflow constraints

Re-check these constraints on the exact `tidb-management-service` ref selected by the dispatch payload:

- Essential and NextGen global declare `auth` as a required string input, parse its fields, and pass the parsed values through job outputs. A `workflow_dispatch` string is not a secret field. The preferred repair is to read API keys, role keys, and account credentials from GitHub environment secrets and keep dispatch inputs non-secret.
- At the inspected revision, NextGen regional declares neither `auth`, `config`, nor `project_id`, but its setup still parses auth/config event fields and its test job reads `project_id`. The runner independently requires a non-empty project ID. There is therefore no complete, declared regional input set at this revision; repair the workflow contract or select a reviewed ref where the declarations and consumers agree before dispatching.
- The regional provider choices are broader than its declared provider-specific scenario-list inputs. The inspected automation scripts only populate the declared AWS or AliCloud list. Do not infer an undeclared list input for another provider.
- All three workflows fetch APITestGen `main` at the inspected revision. The dispatch `ref` changes the `tidb-management-service` workflow revision, not the APITestGen source branch.

## Required secret-backed workflow contract

The runnable dispatch examples below apply only after the selected workflow is repaired so TiDB Cloud API keys, role keys, account token or login credentials, DSNs, provider credentials, and storage tokens are read from GitHub repository or environment secrets and mapped directly to runner environment variables. The workflow must not declare or consume credential-bearing `workflow_dispatch` inputs.

At the inspected revision, Essential and NextGen global require a credential-bearing `auth` string input, and NextGen regional has an incomplete input/consumer contract. Those facts explain the incompatibility; they are not runnable guidance. Do not dispatch those refs until the contract is repaired and reviewed.

The repaired workflow may retain an explicit non-secret control object:

```json
{
  "fetch_from_apitestgen_repo": true,
  "save_result_to_db": false
}
```

Do not add storage tokens or any other credential fields to this object. Wire every required secret directly from GitHub repository/environment secrets.

## Dispatch in the GitHub UI

GitHub documents the UI flow in [Manually running a workflow](https://docs.github.com/en/actions/how-tos/manage-workflow-runs/manually-run-a-workflow?tool=webui).

1. Open a repaired secret-backed workflow under the repository's **Actions** tab and choose **Run workflow**.
2. Select the `tidb-management-service` branch or tag containing that reviewed workflow definition.
3. Fill only non-secret selectors: environment, provider, region, tenant, optional project/host, and the scenario-list field matching the provider.
4. Enter exact APITestGen YAML basenames as a comma-separated list without spaces.
5. Confirm the workflow reads all TiDB Cloud, account, database, provider, and storage credentials from GitHub repository or environment secrets.
6. Do not use the incompatible inspected workflow revisions described above.

## Dispatch with GitHub CLI

Use GitHub CLI only with a repaired secret-backed workflow. `GH_TOKEN` is the transport credential read from the environment; the dispatch body contains non-secret inputs only. GitHub documents this flow in [Manually running a workflow](https://docs.github.com/en/actions/how-tos/manage-workflow-runs/manually-run-a-workflow?tool=cli).

```sh
: "${GH_TOKEN:?load a least-privilege Actions write token}"
: "${CONFIG_JSON:?build from the non-secret config shape}"
export GH_TOKEN CONFIG_JSON

jq -n \
  --arg environment '<environment>' \
  --arg provider '<provider>' \
  --arg region '<region>' \
  --arg tenant '<tenant-id>' \
  --arg scenarios '<scenario-1.yaml,scenario-2.yaml>' \
  '{environment:$environment, cloud_provider:$provider, region:$region,
    tenant_id:$tenant, scenario_yamls_aws:$scenarios,
    config:env.CONFIG_JSON}' |
  gh workflow run '<repaired-workflow-file>' \
    --repo '<owner>/<tidb-management-service-repo>' \
    --ref '<reviewed-tidb-management-service-ref>' \
    --json

unset GH_TOKEN CONFIG_JSON
```

Replace `scenario_yamls_aws` with the exact provider-specific input declared by the repaired workflow. Never add TiDB Cloud or account authentication fields to the dispatch object.

## Dispatch with the REST API

For a repaired secret-backed workflow, POST this non-secret shape:

```json
{
  "ref": "<reviewed-tidb-management-service-ref>",
  "inputs": {
    "environment": "<environment>",
    "cloud_provider": "<provider>",
    "region": "<region>",
    "tenant_id": "<tenant-id>",
    "scenario_yamls_<provider>": "<scenario-1.yaml,scenario-2.yaml>",
    "config": "<non-secret JSON control string>"
  }
}
```

Send it to:

```text
POST https://api.github.com/repos/<owner>/<repo>/actions/workflows/<repaired-workflow-file>/dispatches
```

Use `Accept: application/vnd.github+json`, `Authorization: Bearer <dispatch-token>`, and a currently supported `X-GitHub-Api-Version`. Use `curl --fail-with-body --silent --show-error --location` so HTTP failures propagate. GitHub documents the endpoint and minimum token permission in [REST API endpoints for workflows](https://docs.github.com/en/rest/actions/workflows#create-a-workflow-dispatch-event).

Construct the payload at runtime with `jq` and pipe it to `curl --data-binary @-`. Do not store or print the payload, token header, or response headers. Prefer a GitHub App or fine-grained token with repository Actions write permission. Never include TiDB Cloud or account credentials in dispatch inputs, whether invoked locally or through another host.

## Verify a dispatched run

1. Confirm dispatch succeeded without printing the payload or auth headers.
2. Locate the run by workflow, branch/ref, creation time, and actor. Avoid relying only on the local wrapper run ID.
3. Check `Prepare matrix` for the exact provider-specific YAML list.
4. Check `Fetch scenario cases yaml files` for the exact APITestGen filename and branch.
5. Check `Run scenario cases` and ensure `e2e-tests.xml` reports a non-zero test total.
6. Inspect request/response traces and placeholders without copying credentials into tickets or chat.
7. Confirm summary, teardown, and explicit provider-resource cleanup.
