Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
••••••••••••••••••••
Intelligence View
⚡ tsecurity.de Intelligence

GitHub Actions: Scoping environment variables across environments without wildcards

If you're running a monorepo where multiple apps deploy independently through multiple environments, you'll eventually hit a limitation that GitLab CI handles natively: GitHub Actions doesn't support wildcards for environment variable…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

If you're running a monorepo where multiple apps deploy independently through multiple environments, you'll eventually hit a limitation that GitLab CI handles natively: GitHub Actions doesn't support wildcards for environment variable scoping.



In this post, I'll explain why this becomes a real problem and how to work around it using a single repository variable and a jq one-liner.






The Problem



GitHub Actions supports named environments with their own variables and secrets, configured under Settings → Environments. For a single app with testing, staging, and production environments, this works fine - you define your variables three times and you're done.



The problem arises in a monorepo where multiple apps deploy independently, each with its own GitHub environment per tier. Independent per-app environments are useful because they give you fine-grained protection rules: you can require a reviewer for production/apps/dashboard without blocking production/apps/performance. In a reusable deployment workflow, the environment name is dynamic:




jobs:
deploy:
environment:
name: ${{ inputs.environment }}/apps/${{ inputs.name }}






With ten apps and three tiers, you end up with thirty environments:




testing/apps/dashboard
testing/apps/performance
testing/apps/monitoring
...
staging/apps/dashboard
staging/apps/performance
staging/apps/monitoring
...
production/apps/dashboard
production/apps/performance
production/apps/monitoring
...






Variables like AWS_OIDC_IAM_ROLE_ARN, CDK_DEFAULT_ACCOUNT, or DOMAIN are the same for every app within a tier - all staging environments point to the same AWS account and domain. But GitHub has no wildcard scoping, so you can't say "set DOMAIN=staging.example.com for all staging/* environments" in one place.



Without wildcard support, you have two bad options:




  1. Define every variable on every environment individually - 30 environments × 15 variables = 450 entries to keep in sync

  2. Promote shared variables to the repository level - losing all environment separation



In GitLab, you'd define the variable once with scope staging/* and move on.






The Workaround



Store all environment-tier-specific variables in a single repository variable called ENVIRONMENT_CONFIG as a JSON object:




{
"testing": {
"AWS_OIDC_IAM_ROLE_ARN": "arn:aws:iam::111111111111:role/testing-role",
"CDK_DEFAULT_ACCOUNT": "111111111111",
"DOMAIN": "test.example.com",
"COGNITO_USER_POOL": "eu-central-1_abc123",
"COGNITO_DOMAIN": "auth.test.example.com"
},
"staging": {
"AWS_OIDC_IAM_ROLE_ARN": "arn:aws:iam::222222222222:role/staging-role",
"CDK_DEFAULT_ACCOUNT": "222222222222",
"DOMAIN": "staging.example.com",
"COGNITO_USER_POOL": "eu-central-1_def456",
"COGNITO_DOMAIN": "auth.staging.example.com"
},
"production": {
"AWS_OIDC_IAM_ROLE_ARN": "arn:aws:iam::333333333333:role/production-role",
"CDK_DEFAULT_ACCOUNT": "333333333333",
"DOMAIN": "example.com",
"COGNITO_USER_POOL": "eu-central-1_ghi789",
"COGNITO_DOMAIN": "auth.example.com"
}
}






ENVIRONMENT_CONFIG is a repository variable - not an environment variable - so it's accessible regardless of which GitHub environment the job runs in.



As the first step of the deployment job, extract the right tier and write each key-value pair to $GITHUB_ENV:




- name: Load environment variables from repository variables
run: |
echo '${{ vars.ENVIRONMENT_CONFIG }}' | jq -r '.${{ inputs.environment }} | to_entries[] | "\(.key)=\(.value)"' >> $GITHUB_ENV






jq selects the object for the current environment (e.g., staging), converts each entry to KEY=VALUE format, and appends it to $GITHUB_ENV. Everything written to $GITHUB_ENV is available to all subsequent steps.



These vars.* references will be empty at job start - they exist only to document which variables the job expects. The Load environment variables step overwrites them via $GITHUB_ENV.




jobs:
deploy:
environment:
name: ${{ inputs.environment }}/apps/${{ inputs.name }}
env:
AWS_OIDC_IAM_ROLE_ARN: ${{ vars.AWS_OIDC_IAM_ROLE_ARN }}
CDK_DEFAULT_ACCOUNT: ${{ vars.CDK_DEFAULT_ACCOUNT }}
DOMAIN: ${{ vars.DOMAIN }}
COGNITO_USER_POOL: ${{ vars.COGNITO_USER_POOL }}
COGNITO_DOMAIN: ${{ vars.COGNITO_DOMAIN }}
steps:
- uses: actions/checkout@v6

- name: Load environment variables from repository variables
run: |
echo '${{ vars.ENVIRONMENT_CONFIG }}' | jq -r '.${{ inputs.environment }} | to_entries[] | "\(.key)=\(.value)"' >> $GITHUB_ENV

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: ${{ env.AWS_OIDC_IAM_ROLE_ARN }}
aws-region: ${{ vars.AWS_DEFAULT_REGION }}






The env: block is evaluated once at job start - at that point vars.AWS_OIDC_IAM_ROLE_ARN is empty. The Load environment variables from repository variables step writes the correct value to $GITHUB_ENV, and all subsequent steps read from there. By the time Configure AWS credentials runs, ${{ env.AWS_OIDC_IAM_ROLE_ARN }} resolves to the correct value for the tier.






When this approach doesn't work:



This workaround is best suited for:




  • Non-sensitive configuration values

  • Values that change per environment tier, not per app



Consider alternatives if:




  • You need to store secrets (use GitHub Secrets instead)

  • You have app-specific variables (use environment variables on the GitHub environment)



I hope this post helps you manage environment-specific configuration without drowning in repeated variable definitions.






If you have any kind of feedback, suggestions or ideas - feel free to comment this post!

1. Sofort-Triage & Abwehrmaßnahmen

SOC Incident Playbook: Vulnerability Remediation & Verification
Syntax validiert (0 Fehler)
title: Detect Exploitation - GitHub Actions: Scoping environment variables across environments without wildcards
id: 82026bc6-28d3-4612-b5e2-9a3d63e2aaa1
status: experimental
description: Automatisch generierte SIEM-Erkennungsregel basierend auf CTI Intelligence
references:
  - https://tsecurity.de/
author: iShareStuff CTI Automated Detection Engine
date: 2026-09-25
logsource:
  category: network_connection
  product: any
detection:
  selection:
      CommandLine|contains:
        - 'exploit'
  condition: selection
falsepositives:
  - Legitime administrative Zugriffe oder Penetrationstests
level: high
tags:
  - attack.initial_access
Syntax validiert (0 Fehler)
rule CTI_Threat_Indicator {
    meta:
        author = "iShareStuff CTI Automated Detection Engine"
        date = "2026-09-25"
        description = "YARA Signature for "
    strings:
        $str = "GitHub Actions: Scoping enviro" ascii wide
    condition:
        any of them
}
Syntax validiert (0 Fehler)
index=security sourcetype IN ("cisco:asa", "pan:traffic", "zeek_conn", "suricata", "WinEventLog:Security")
("GitHub Actions Scoping environment varia")
| stats count earliest(_time) as first_seen latest(_time) as last_seen by src_ip, dest_ip, dest_host, signature
| eval first_seen=strftime(first_seen, "%Y-%m-%d %H:%M:%S"), last_seen=strftime(last_seen, "%Y-%m-%d %H:%M:%S")
| sort - count
Syntax validiert (0 Fehler)
message: "*GitHub Actions Scoping environment varia*"
Syntax validiert (0 Fehler)
CommonSecurityLog
| where Message has "GitHub Actions Scoping environment varia"
| summarize EventCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, DestinationIP, DestinationPort, Activity
| extend DetectionRule = "iShareStuff-CTI-Compiled"
| sort by EventCount desc

2. Cyber Threat Intelligence & Forensik

🎯
MITRE ATT&CK Matrix Navigator 14 Taktiken
Reconnaissance
-
Resource Development
-
Initial Access
Execution
Persistence
-
Privilege Escalation
Defense Evasion
Credential Access
-
Discovery
-
Lateral Movement
-
Collection
-
Command and Control
Exfiltration
-
Impact
tsecurity.de Cognitive Threat RAG
Fokus-Vektor:

Kognitive Analyse für identifizierte Bedrohung: Erhöhte Bedrohungslage im Bereich GitHub Actions: Scoping environment vari.... Basierend auf 368k Vektor-Korrelationen werden sofortige Isolationsmaßnahmen für betroffene Endpunkte empfohlen.

🛡️ Angriffsfläche & Exposure

Netzwerk/Remote-Zugriff ohne Vorauthentifizierung möglich.

⚡ Empfohlene Sofortmaßnahmen
  • 1. Perimeter-Inspektion: Relevante Portfreigaben und exponierte Endpunkte unverzüglich scannen.
  • 2. Patch-Applikation: Hersteller-Hotfix einspielen oder betroffene Daemons in isolierte DMZ-Segmente überführen.
  • 3. Telemetrie & EDR-Alerts: Prozessaufrufe und Child-Processes auf anomale Shell-Spawns überwachen.
🔗 Semantisch verwandte Zero-Days MariaDB 11.7 VEC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten GitHub Actions: Scoping environment variables across environments without wildcards

Thematisch verwandte Begriffe: GitHub, Actions, Scoping, environment · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-87722 | Uncontrolled Resource Consumption (CWE-400 / CWE-1333) in regex search q…
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel • Rechts: nächster Artikel • unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel TTP ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...
↗ Original-Quelle