A reusable GitHub Action that loads and parses JSON workflow configuration files from .github/workflow-config.json. This action centralizes configuration management for container scanning and other workflows, reducing workflow complexity and improving maintainability.
- Reduced Workflow Complexity: 6 runtime inputs instead of 15+ (60% reduction)
- Configuration Reusability: One config file shared across multiple workflows
- Version Control: Config files are versioned and discoverable in repositories
- Team Flexibility: Customize scanning policies without modifying workflows
- Vault Integration: Automatic secret management for private repositories
- Backward Compatible: Works alongside existing workflow inputs
Create .github/workflow-config.json:
{
"container_scanning": {
"secrets": {
"vault": {
"secret_path": "/path/to/secret",
"aws_role": "/path/to/aws/role"
}
},
"fossa": {
"policy": {
"mode": "REPORT",
"block_on": ["policy_conflict"]
},
"vulnerability": {
"mode": "BLOCK",
"block_on": ["critical", "high"]
},
"team": "Platform Team",
"labels": ["production", "container"]
}
},
"slack_channel": "#team-notifications"
}Use in workflow:
- name: Load Workflow Configuration
id: config
uses: SolaceDev/solace-public-workflows/workflow-config-loader@main
with:
config_file: .github/workflow-config.json
config_type: container_scanning
- name: Use Configuration Values
run: |
echo "Vault Path: ${{ steps.config.outputs.vault_secret_path }}"
echo "FOSSA Team: ${{ steps.config.outputs.fossa_team }}"
echo "Licensing Mode: ${{ steps.config.outputs.fossa_licensing_mode }}"No config file needed - pass secrets directly to workflows.
| Input | Required | Description |
|---|---|---|
config_file |
Yes | Path to JSON configuration file (e.g., .github/workflow-config.json) |
config_type |
Yes | Type of configuration to parse: container_scanning, sca_scanning, etc. |
| Output | Description |
|---|---|
vault_url |
Vault URL (typically from vars.GCP_VAULT_ADDR) |
vault_secret_path |
Vault secret path for API keys |
vault_aws_role |
Vault AWS STS role path for ECR authentication |
| Output | Description |
|---|---|
fossa_licensing_mode |
Licensing check mode: BLOCK or REPORT |
fossa_licensing_block_on |
Comma-separated licensing issues to block on |
fossa_vulnerability_mode |
Vulnerability check mode: BLOCK or REPORT |
fossa_vulnerability_block_on |
Comma-separated vulnerability severities to block on |
fossa_project_id |
FOSSA project ID override |
fossa_team |
FOSSA team name for project assignment |
fossa_labels |
Comma-separated FOSSA project labels |
| Output | Description |
|---|---|
config_json |
Raw configuration JSON (for advanced use cases) |
slack_channel |
Slack notification channel |
The action parses JSON configuration with the following structure:
{
"container_scanning": {
"secrets": {
"vault": {
"secret_path": "string",
"aws_role": "string"
}
},
"fossa": {
"policy": {
"mode": "BLOCK | REPORT",
"block_on": ["policy_conflict", "policy_flag"]
},
"vulnerability": {
"mode": "BLOCK | REPORT",
"block_on": ["critical", "high", "medium", "low"]
},
"project_id": "string or null",
"team": "string",
"labels": ["string"]
}
},
"slack_channel": "string"
}When fields are not specified, the action uses these defaults:
| Field | Default Value |
|---|---|
vault_secret_path |
/path/to/secret |
slack_channel |
#your-slack-channel |
fossa.policy.mode |
REPORT |
fossa.policy.block_on |
["policy_conflict"] |
fossa.vulnerability.mode |
REPORT |
fossa.vulnerability.block_on |
["critical", "high"] |
{
"container_scanning": {
"fossa": {
"policy": {
"mode": "REPORT"
},
"vulnerability": {
"mode": "BLOCK",
"block_on": ["critical", "high"]
}
}
}
}{
"container_scanning": {
"secrets": {
"vault": {
"secret_path": "/path/to/secret",
"aws_role": "/path/to/aws/role"
}
},
"fossa": {
"policy": {
"mode": "BLOCK",
"block_on": ["policy_conflict", "policy_flag"]
},
"vulnerability": {
"mode": "BLOCK",
"block_on": ["critical", "high"]
},
"team": "Platform Engineering",
"labels": ["production", "container", "critical-path"],
"project_id": "custom_SolaceDev_my-project"
}
},
"slack_channel": "#platform-alerts"
}{
"squad": "Platform Team",
"service_name": "my-service",
"slack_channel": "#team-notifications",
"container_scanning": {
"fossa": {
"team": "Platform Team",
"labels": ["production"]
}
},
"sca_scanning": {
"enabled": true
}
}name: Container Security Scan
on:
pull_request:
push:
branches: [main]
jobs:
scan:
uses: SolaceDev/solace-public-workflows/.github/workflows/container-scan-and-guard.yaml@main
with:
container_image: "my-registry/my-image:${{ github.sha }}"
use_vault: true
vault_url: ${{ vars.GCP_VAULT_ADDR }}
config_file: ".github/workflow-config.json"The workflow will automatically:
- Load configuration from
.github/workflow-config.json - Retrieve secrets from Vault using the configured paths
- Apply FOSSA policies and team assignments
- Send notifications to the configured Slack channel
jobs:
custom_scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Load Config
id: config
uses: SolaceDev/solace-public-workflows/workflow-config-loader@main
with:
config_file: .github/workflow-config.json
config_type: container_scanning
- name: Use Config Values
run: |
echo "Team: ${{ steps.config.outputs.fossa_team }}"
echo "Labels: ${{ steps.config.outputs.fossa_labels }}"
if [ "${{ steps.config.outputs.fossa_licensing_mode }}" = "BLOCK" ]; then
echo "Licensing violations will block the build"
fi- Loads JSON File: Reads and validates
.github/workflow-config.json - Parses Configuration: Extracts values for the specified
config_type - Applies Defaults: Uses sensible defaults for missing optional fields
- Outputs Values: Makes all configuration available as action outputs
- Logs Summary: Displays parsed configuration for transparency
The action will fail with clear error messages if:
- Config file not found:
❌ Configuration file not found: .github/workflow-config.json - Invalid JSON:
❌ Invalid JSON syntax in .github/workflow-config.json - Missing required fields: Specific error indicating which field is required
Before (15+ workflow inputs):
- uses: SolaceDev/solace-public-workflows/.github/workflows/container-scan-and-guard.yaml@main
with:
container_image: "my-image:tag"
fossa_licensing_mode: "BLOCK"
fossa_licensing_block_on: "policy_conflict"
fossa_vulnerability_mode: "BLOCK"
fossa_vulnerability_block_on: "critical,high"
vault_secret_path: "/path/to/secret"
vault_aws_role: "/path/to/aws/role"
slack_channel: "#your-slack-channel"
# ... many more inputsAfter (6 workflow inputs):
- uses: SolaceDev/solace-public-workflows/.github/workflows/container-scan-and-guard.yaml@main
with:
container_image: "my-image:tag"
use_vault: true
vault_url: ${{ vars.GCP_VAULT_ADDR }}
config_file: ".github/workflow-config.json"All policy and team configuration moves to .github/workflow-config.json.
- Full Schema Reference: See the comprehensive schema documentation in this directory
- Container Scanning Framework: container/container-scan/README.md
- FOSSA Integration: container/fossa-scan/README.md
- Architecture Design: Container Scan Architecture
For questions or issues:
- Report bugs in the solace-public-workflows repository
- Refer to schema documentation for configuration options
- Check workflow logs for detailed parsing output