Available in every lifecycle script (setup / check / solve / cleanup) without configuration. Cloud credentials inject only when a matching resource block exists in config.yml.
Participant & userAlways set
INSTRUQT_PARTICIPANT_ID
Stable per-play identifier.
INSTRUQT_USER_ID
Stable user identifier.
INSTRUQT_USER_NAME
Display name.
INSTRUQT_USER_EMAIL
May be empty on invite-link plays. Guard with a fallback.
Track & sandboxAlways set
INSTRUQT_TRACK_SLUG
Track’s slug string.
INSTRUQT_TRACK_ID
Platform-assigned UUID. Distinct from slug.
_SANDBOX_ID
Sandbox identifier. Shell env only — not in the agent variable store.
Terraform AzureRM-style aliases. Use directly in provider blocks.
AZURE_LOCATION
Subscription’s configured region.
Notes
{NAME} is the resource’s name: field uppercased with hyphens replaced by underscores. name: my-lab → INSTRUQT_AWS_ACCOUNT_MY_LAB_*. Forgetting to uppercase or mishandling hyphens is a common foot-gun.
_SANDBOX_ID is a shell env var, not an agent variable. To surface it in assignment.md, run agent variable set SANDBOX_ID “$_SANDBOX_ID” in track-level setup.
INSTRUQT_USER_EMAIL is not guaranteed in all play contexts (invite links without registration). Guard with: EMAIL="${INSTRUQT_USER_EMAIL:-guest@example.com}".
When the account name is parameterized, use bash indirect expansion: SA_KEY="INSTRUQT_GCP_PROJECT_${PROJECT_NAME}_ADMIN_SERVICE_ACCOUNT_KEY"; echo "${!SA_KEY}" | base64 -d > /tmp/sa.json.
Auto-injected creds appear only when the matching aws_accounts: / azure_subscriptions: / gcp_projects: block exists in config.yml. Without the resource block, the variables are empty and CLI calls fail with cryptic auth errors rather than “variable not set.”