Skip to main content

GitHub AST Orchestrator

The Conviso Platform GitHub AST Orchestrator runs Conviso AST from one GitHub repository (the orchestrator). Application repositories do not need a Conviso workflow.

When an eligible pull request is merged, Conviso calls GitHub Actions workflow_dispatch on the orchestrator and passes the target repository and branch. The workflow obtains a short-lived clone credential from the Platform (using your API key), checks out the target repository, runs conviso-ast, and sends findings to the mapped asset.

You do not store a GitHub Personal Access Token for cloning.

How it works​

What Conviso checks before dispatching:

  1. The event is a pull request that was merged (action: closed and merged: true).
  2. AST Scans is enabled on the GitHub integration.
  3. The repository is an imported asset that is enabled.
  4. The PR base branch matches the configured merge target (see Merge target branch below).

The Actions run always appears on the orchestrator repository (not on the application repository).

note

Execution costs: Jobs run on your GitHub Actions runners and consume your organization’s Actions minutes.

Before you begin​

Work in this order: GitHub setup first, then Conviso Platform.

You need:

  • GitHub Integration connected (GitHub App installed).
  • At least one application repository imported as an asset and enabled.
  • A dedicated orchestrator repository (or an empty repo you will use only for this). Example / template: convisoappsec/pipeline-orchestrator.
  • Permission to create an Actions repository secret on the orchestrator.
  • A Conviso API key for the same environment you will scan against (production or staging).
  • The GitHub App must have access to the orchestrator and to every target repository you will scan. Prefer All repositories on the App installation.
TermExact meaning
Orchestrator repositoryGitHub repo that contains .github/workflows/ast.yml. Conviso triggers this repo only.
Target repositoryApplication repo imported as an asset. It must not rely on a local Conviso workflow for this flow.
RefBranch or tag of the orchestrator where GitHub loads ast.yml when Conviso calls workflow_dispatch. If you leave Ref empty in Conviso, dispatch defaults to main.
Merge target branchThe PR base branch on the target repo that is allowed to trigger a scan (for example main). See below.
AssetImported repository in Conviso (owner/repo) where findings are stored.

Merge target branch​

Conviso compares the merged PR’s base branch to:

  1. The asset’s configured AST / branch mapping, if set; otherwise
  2. The integration Ref (orchestrator_ref).
ConfigurationWhat triggers a scan
Asset branch = master, Ref = mainOnly merges into master on that asset
Asset branch empty, Ref = mainOnly merges into main on that asset
Asset branch empty and Ref emptyNo branch filter (any base branch can trigger). Prefer setting Ref explicitly.

Ref is still the orchestrator branch that holds the workflow. It is reused as the default merge-target filter when the asset has no branch of its own. Those are two roles of the same field β€” do not confuse β€œwhere ast.yml lives” with β€œany branch on the target”.


Part 1 – GitHub setup​

Step 1 – Create the orchestrator repository​

  1. Create a GitHub repository (recommended name: conviso-ast-orchestrator), or copy from convisoappsec/pipeline-orchestrator and keep only .github/workflows/ast.yml.
  2. Choose the branch that will contain the workflow (almost always main). That value is what you will set as Ref in Conviso.

Step 2 – Create the CONVISO_API_KEY secret​

In the orchestrator repository (not the target):

  1. Open Settings β†’ Secrets and variables β†’ Actions.
  2. Under Repository secrets, create:
NameTypeRequired
CONVISO_API_KEYRepository secretYes

Use the API key for the same Conviso environment as the Platform you configured (production vs staging).

Repository secret CONVISO_API_KEY under Settings β†’ Secrets and variables β†’ Actions.

Repository secret CONVISO_API_KEY

Optional variable

You may add an Actions variable CONVISO_COMPANY_ID. The workflow uses it only when the company_id input is empty (typical for a manual Run workflow). When Conviso dispatches after a merge or Run AST, it sends company_id in the inputs, so the variable is not required for Platform-triggered runs.

Do not create a GitHub PAT for clone. The workflow calls conviso-ast-repository-token --provider github, and the Platform returns a GitHub App installation token scoped to the single target repository, with read-only contents access, valid for about one hour.

Step 3 – Add .github/workflows/ast.yml​

GitHub Actions only loads workflows from .github/workflows/. A file at the repository root is ignored.

Example repository

On the orchestrator branch you will set as Ref (usually main):

  1. Create .github/workflows/ if needed.
  2. Create ast.yml so the full path is exactly .github/workflows/ast.yml.
  3. Paste the YAML below (or copy it from the example repo).

Orchestrator repository with .github/workflows/ast.yml on main.

.github/workflows/ast.yml in the orchestrator repository

name: AST Scan Orchestrator

on:
workflow_dispatch:
inputs:
repo_full_name:
description: "Repository to scan (owner/repo)"
required: true
type: string
branch:
description: "Branch to scan"
required: true
type: string
commit_sha:
description: "Merge commit SHA (post-merge)"
required: false
type: string
pr_number:
description: "Pull request number (post-merge)"
required: false
type: string
api_url:
description: "Conviso API URL"
required: false
type: string
default: https://api.convisoappsec.com
company_id:
description: "Conviso company id"
required: false
type: string
asset_id:
description: "Conviso asset id"
required: false
type: string
scan_run_id:
description: "Scan run id from the platform"
required: false
type: string

jobs:
run-ast-scan:
runs-on: ubuntu-latest
container:
image: convisoappsec/convisoast_v2:latest

steps:
- name: Get repository token
id: repo_token
env:
CONVISO_APIKEY: ${{ secrets.CONVISO_API_KEY }}
API_URL: ${{ inputs.api_url }}
CONVISO_REPO_FULL_NAME: ${{ inputs.repo_full_name }}
ASSET_ID: ${{ inputs.asset_id }}
SCAN_RUN_ID: ${{ inputs.scan_run_id }}
run: |
set -euo pipefail
export CONVISO_BASE_URL="${API_URL:-https://api.convisoappsec.com}"
CONVISO_BASE_URL="${CONVISO_BASE_URL%/}"
case "$CONVISO_BASE_URL" in
https://app.convisoappsec.com)
export CONVISO_BASE_URL="https://api.convisoappsec.com"
;;
https://staging.convisoappsec.com)
export CONVISO_BASE_URL="https://api.staging.convisoappsec.com"
;;
esac
case "${ASSET_ID:-}" in
""|none|0) unset CONVISO_ASSET_ID || true ;;
*) export CONVISO_ASSET_ID="$ASSET_ID" ;;
esac
case "${SCAN_RUN_ID:-}" in
""|none|0) unset CONVISO_SCAN_RUN_ID || true ;;
*) export CONVISO_SCAN_RUN_ID="$SCAN_RUN_ID" ;;
esac
TOKEN=$(conviso-ast-repository-token --provider github)
echo "::add-mask::$TOKEN"
echo "token=$TOKEN" >> "$GITHUB_OUTPUT"
echo "base_url=$CONVISO_BASE_URL" >> "$GITHUB_OUTPUT"

- name: Checkout target repository
uses: actions/checkout@v6
with:
repository: ${{ inputs.repo_full_name }}
ref: ${{ inputs.branch }}
fetch-depth: 0
token: ${{ steps.repo_token.outputs.token }}

- name: Run Conviso AST
env:
CONVISO_APIKEY: ${{ secrets.CONVISO_API_KEY }}
CONVISO_BASE_URL: ${{ steps.repo_token.outputs.base_url }}
CONVISO_COMPANY_ID: ${{ inputs.company_id || vars.CONVISO_COMPANY_ID }}
ASSET_ID: ${{ inputs.asset_id }}
SCAN_RUN_ID: ${{ inputs.scan_run_id }}
CONVISO_BRANCH: ${{ inputs.branch }}
GIT_CONFIG_COUNT: "1"
GIT_CONFIG_KEY_0: safe.directory
GIT_CONFIG_VALUE_0: "*"
run: |
set -euo pipefail
case "${ASSET_ID:-}" in
""|none|0) unset CONVISO_ASSET_ID || true ;;
*) export CONVISO_ASSET_ID="$ASSET_ID" ;;
esac
case "${SCAN_RUN_ID:-}" in
""|none|0) unset CONVISO_SCAN_RUN_ID || true ;;
*) export CONVISO_SCAN_RUN_ID="$SCAN_RUN_ID" ;;
esac
conviso-ast -p . -o /tmp/conviso-ast-session.zip

- name: Upload session log
if: always()
uses: actions/upload-artifact@v4
with:
name: conviso-ast-session
path: /tmp/conviso-ast-session.zip
if-no-files-found: ignore
  1. Commit and push to that Ref branch.
important
  • Path on disk: .github/workflows/ast.yml only.
  • In Conviso, set the workflow field to the file name ast.yml (not .github/workflows/ast.yml). Conviso normalizes a full path to the basename, but the UI expects the file name used by the GitHub Actions API.
  • This template checks out inputs.branch (the PR base branch after merge). Conviso also sends commit_sha and pr_number for correlation; the template above does not pass commit_sha into actions/checkout.

Part 2 – Conviso Platform setup​

Step 4 – Configure the orchestrator​

  1. Open Integrations β†’ GitHub.
  2. Turn AST Scans on.
    (GitHub Advanced Security is a separate toggle. It is not required for the orchestrator merge flow described here.)
  3. Fill Orchestrator Configuration:
    • Orchestrator Repo β€” owner/repo of the orchestrator.
    • Workflow Filename or ID β€” ast.yml.
    • Ref β€” orchestrator branch/tag that contains .github/workflows/ast.yml (e.g. main). If empty, Conviso dispatches with ref main.
  4. Save.

Orchestrator Configuration

Step 5 – Assets and merge target​

  1. Confirm each application repository is imported and enabled.
  2. Set the asset branch mapping when the merge target is not the same as Ref (example: Ref main on the orchestrator, merges into master on the asset β†’ map the asset to master).
  3. If the asset has no branch mapping, merges must go into the branch named by Ref (or any branch only if Ref is also empty β€” avoid that setup).

End-to-end flow (after setup)​

  1. Developer merges a PR into the configured merge target on an imported, enabled asset.
  2. Conviso validates the event and configuration, then calls workflow_dispatch on owner/orchestrator / ast.yml / Ref.
  3. Inputs include at least: repo_full_name, branch (PR base), commit_sha, pr_number, api_url, company_id, asset_id (blank values may be omitted).
  4. Job steps: issue repository token β†’ checkout target at branch β†’ run conviso-ast β†’ upload session artifact.
  5. Findings appear on the asset in Conviso Platform.
  6. In GitHub, open the orchestrator β†’ Actions β†’ AST Scan Orchestrator to inspect the run.

Validation checklist​

CheckExpected
SecretCONVISO_API_KEY exists on the orchestrator
Path.github/workflows/ast.yml is on the Ref branch
ConvisoOrchestrator owner/repo + ast.yml + Ref saved; AST Scans on
AssetTarget repo imported, enabled; merge target branch matches mapping or Ref
After mergeNew run under orchestrator Actions; findings (or a clean result) on the asset

Successful orchestrator run: Get repository token β†’ Checkout β†’ Run Conviso AST.

Successful AST Scan Orchestrator Actions run

Scan result on the asset in Conviso Platform (Conviso AST).

Successful Conviso AST scan on the Platform

Manual test (optional): on the orchestrator, Actions β†’ AST Scan Orchestrator β†’ Run workflow. Set repo_full_name and branch to an imported asset. Set api_url if you are not on production defaults. Set company_id or define CONVISO_COMPANY_ID.

Troubleshooting​

SymptomCause / fix
Merge done, no Actions runAST Scans off; orchestrator fields incomplete; asset disabled or not imported; PR base branch β‰  asset branch / Ref; GitHub App cannot see the repos
Workflow never listedFile not under .github/workflows/, or not on the Ref branch Conviso uses
Token step fails (HTTP 4xx)repo_full_name not an imported asset for that API key/company; wrong environment (CONVISO_API_KEY vs api_url)
Checkout 403GitHub App lacks access to the target repository
Scanner missing CONVISO_COMPANY_IDManual run without company_id input and without variable CONVISO_COMPANY_ID
Wrong code scannedMerge target / branch input mismatch; confirm you merged into the configured base branch

Contribute to the Docs

Found something outdated or missing? Help us improve the documentation with a quick suggestion or edit.

How to contribute

Resources

By exploring our content, you'll find resources that will enhance your understanding of the importance of a Security Application Program.

Conviso Blog: Explore our blog, which offers a collection of articles and posts covering a wide range of AppSec topics. The content on the blog is primarily in English.

Conviso's YouTube Channel: Access a wealth of informative videos covering various topics related to AppSec. Please note that the content is primarily in Portuguese.