CI/CD Integration

Stop governance issues
before they reach production.

One call in your pipeline. Flowcerta validates the workflow file, scores it against your governance ruleset, preserves the pipeline context that triggered the run, and returns a 422 if blocking findings are present. No custom exit-code logic. No manual review step.

GitHub ActionsPower Platform PipelinesAny curl-capable runnermetadata -> pipeline context in appenforcement_mode: advisory | warning | blocking
Setup

Four steps from zero to gate.

01

Create an API key

Open Team -> API Keys in the app. Create a key with analysis:write scope. Takes 30 seconds.

02

Add it as a CI secret

Store the key as FLOWCERTA_API_KEY in GitHub Actions secrets, Power Automate secure inputs, or your runner secret manager. Never commit raw keys.

03

Add one step to your pipeline

Post the workflow file to /api/v1/validate with enforcement_mode=blocking and attach metadata so repository, branch, run, or deployment context survives into Flowcerta.

04

Review runs in the Validations feed

Every pipeline run lands in the same Validations feed your team already uses, labelled with repository, branch, run, or Power Platform deployment context.

GitHub ActionsYAML step

Add to any workflow job

Drop this step into an existing job that runs after your workflow files are ready. The metadata payload preserves repo, branch, PR, and run details in Flowcerta.

- name: Flowcerta governance gate
  env:
    FLOWCERTA_API_KEY: ${{ secrets.FLOWCERTA_API_KEY }}
  run: |
    PR_URL=""
    if [ "${{ github.event_name }}" = "pull_request" ]; then
      PR_URL="https://github.com/${{ github.repository }}/pull/${{ github.event.pull_request.number }}"
    fi

    METADATA=$(jq -nc \
      --arg repo "${{ github.repository }}" \
      --arg branch "${{ github.ref_name }}" \
      --arg commit "${{ github.sha }}" \
      --arg prUrl "$PR_URL" \
      --arg workflowRunUrl "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
      '{
        provider: "github-actions",
        pipeline: {
          provider: "github-actions",
          repository: $repo,
          branch: $branch,
          commit: ($commit[0:7]),
          prUrl: ($prUrl | select(. != "")),
          workflowRunUrl: $workflowRunUrl
        }
      }')

    curl -X POST "https://app.flowcerta.com/api/v1/validate" \
      -H "Authorization: ApiKey $FLOWCERTA_API_KEY" \
      -F "file=@workflows/Main.xaml" \
      -F "platform=uipath" \
      -F "enforcement_mode=blocking" \
      -F "source=cicd" \
      -F "label=${{ github.workflow }} #${{ github.run_number }}" \
      -F "metadata=$METADATA"
  # Returns 422 on critical/high findings -> job fails automatically
Raw APIcurl wrapper

Use from any runner

If you already have your own orchestration layer, call the API directly and send the same normalized metadata contract yourself.

curl -X POST "https://app.flowcerta.com/api/v1/validate" \
  -H "Authorization: ApiKey $FLOWCERTA_API_KEY" \
  -F "file=@flows/InvoiceApproval.json" \
  -F "platform=power_automate" \
  -F "enforcement_mode=blocking" \
  -F "source=cicd" \
  -F "label=contoso/rpa-bots / qa / InvoiceApproval.json" \
  -F 'metadata={
    "provider":"github-actions",
    "pipeline":{
      "provider":"github-actions",
      "repository":"contoso/rpa-bots",
      "branch":"main",
      "commit":"a3f8b2c",
      "workflowRunUrl":"https://github.com/contoso/rpa-bots/actions/runs/9001"
    }
  }'
Power PlatformExtension flow

Wrap Power Platform Pipelines

Use a pipeline-triggered cloud flow to call Flowcerta and preserve deployment, solution, and target environment context on the validation result.

Power Platform pipeline extension flow:

1. Trigger: "When a pipeline deployment completes"
2. Compose metadata:

{
  "provider": "power_platform",
  "pipeline": {
    "provider": "power_platform",
    "host": "power-platform-pipelines",
    "pipeline_name": "@{triggerBody()?['pipeline']?['name']}",
    "stage_name": "@{triggerBody()?['stage']?['name']}",
    "deployment_id": "@{triggerBody()?['deployment']?['id']}",
    "solution_name": "@{triggerBody()?['solution']?['uniqueName']}",
    "solution_version": "@{triggerBody()?['solution']?['version']}",
    "environment_name": "@{triggerBody()?['targetEnvironment']?['displayName']}",
    "environment_id": "@{triggerBody()?['targetEnvironment']?['id']}",
    "deployment_url": "@{triggerBody()?['deployment']?['link']}"
  }
}

3. HTTP action:
   POST https://app.flowcerta.com/api/v1/validate
   Authorization: ApiKey <FLOWCERTA_API_KEY>
   form-data:
     file = exported workflow package
     platform = power_automate
     source = cicd
     enforcement_mode = blocking
     label = @{triggerBody()?['pipeline']?['name']} / @{triggerBody()?['stage']?['name']}
     metadata = <Compose output>
Enforcement

Start observing. Enforce when ready.

Set enforcement_mode on each request. Switch from advisory to blocking without changing any other pipeline config.

advisoryHTTP 200

Always passes

Findings are returned but the pipeline is never blocked. Use this to baseline your estate before enforcing.

warningHTTP 200

Soft gate

Returns 200 even on high-severity findings. Full findings in the response body. Visibility without breaking CI.

Rule coverage

What gets caught at the gate.

The default ruleset runs on every validation. Critical and high findings block the pipeline in blocking mode.

criticalCRED-001Hardcoded connection stringsPlaybook ->
criticalCRED-002Hardcoded API keys and secretsPlaybook ->
highERR-001External calls without Try/CatchPlaybook ->
highPII-001PII access without audit loggingPlaybook ->
highPII-002PII written to log messagesPlaybook ->
mediumANL-007Missing log messagesPlaybook ->

Browse all 18 rules ->

Add the gate. Ship with confidence.

Create a free API key, test against one workflow file, then drop the step or flow into your pipeline. The whole setup takes under 10 minutes.