Control Repo Guide
Use a dedicated control repo to run baseliner on a schedule.
What the control repo contains
.github/workflows/baseliner.yml(fromexamples/control-repo-workflow.yml)baseliner.yaml(fromexamples/baseliner.yaml)- One secret:
BASELINER_TOKEN
Token requirements
Use either:
- A classic PAT with
reposcope, or - A fine-grained PAT with repository permissions:
- Metadata: Read
- Contents: Read
- Issues: Write (only needed for
--open-issues)
Token scope must include every repository you plan to scan.
If your org uses SAML SSO, authorize the token for the org after creation.
Using the GitHub Action
The simplest workflow uses baselinerhq/baseliner-action — no install boilerplate:
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: baselinerhq/baseliner-action@v1
with:
config: baseliner.yaml
output-file: results.json
env:
GITHUB_TOKEN: ${{ secrets.BASELINER_TOKEN }}
- uses: actions/upload-artifact@v4
if: always()
with:
name: baseliner-results
path: results.jsonInputs map to the CLI flags (format, sarif-file, fail-under, open-issues, …). Or use the install-script template below.
Privacy: scanning private repos from a public control repo
If your control repo is public but its token can read private repos, the aggregate output would leak private repo names and findings into public view — the console table is in the public Actions log, and results.json / SARIF are public artifacts. (Per-repo --open-issues issues are not a leak: they open inside each scanned repo, so a private repo's issue stays private.)
The baseliner-action handles this for you: it detects the control repo's visibility (github.event.repository.private) and, when the repo is public, enables the privacy guard automatically. Private/internal repos are redacted by default (shown as private/1 with score but no name or finding detail). No configuration needed.
To choose a different treatment, set it in baseliner.yaml:
privacy:
private_repos: exclude # redact (default) | exclude | fail | allowOutside the Action (raw CLI), signal a public context explicitly with --public-context or privacy.public_context: true. Full details and the mode table are in Configuration → Privacy guard.
Setup checklist
- Create or choose a control repo.
- Copy the workflow template:bash
mkdir -p .github/workflows curl -fsSL https://raw.githubusercontent.com/baselinerhq/baseliner/main/examples/control-repo-workflow.yml \ -o .github/workflows/baseliner.yml - Copy config and edit scope filters:bash
curl -fsSL https://raw.githubusercontent.com/baselinerhq/baseliner/main/examples/baseliner.yaml \ -o baseliner.yaml - Add secret
BASELINER_TOKENin Settings -> Secrets and variables -> Actions. - Trigger
workflow_dispatch. - Confirm:
- Workflow run completes.
results.jsonuploads as artifact.- When
--open-issuesis enabled, findings issue is created/updated.
Manual smoke test (local)
Run against a non-production account or org first.
export GITHUB_TOKEN=<your_pat>
baseliner scan \
--config examples/baseliner.yaml \
--output-file /tmp/results.json \
--open-issues \
--format both \
--verboseValidate:
- Discovery count matches expected repos.
- Include/exclude filters behave as expected.
/tmp/results.jsonexists and parses.- Re-run updates existing findings issue (no duplicates).
--dry-runperforms no write actions.