CI gate action for your GitHub repositories. Connects to the Fluid Attacks platform and checks whether your repository has open vulnerabilities reported by Fluid Attacks. Requires a Fluid Attacks account and a CI Gate token.
In your repository, go to Settings → Secrets and variables → Actions and create a new secret named FA_API_TOKEN with your CI Gate token.
To generate or retrieve the token, go to Organization → Groups → GroupName → DevSecOps in the Fluid Attacks platform and click Manage token. The token is valid for 180 days.
Add the file .github/workflows/ci-gate.yml to your repository:
name: Fluid Attacks CI Gate
on:
pull_request_target:
types: [opened, synchronize, reopened]
jobs:
ci-gate:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: fluidattacks/ci-gate-action@<version>
id: gate
with:
api_token: ${{ secrets.FA_API_TOKEN }}
repo_name: my-repoReplace <version> with the latest release tag and my-repo with the repository nickname configured in the Fluid Attacks platform. Push the file and the check will run automatically.
Why
pull_request_targetinstead ofpull_request? GitHub withholds secrets from workflows triggered bypull_requestwhen the PR comes from a fork, so the action would fail to authenticate.pull_request_targetruns in the context of the base branch and always has access to secrets. This is safe here because the action never checks out or executes any code from the PR — it only calls the Fluid Attacks API.
- A Fluid Attacks account with an active group and a repository configured on the platform.
- A CI Gate token generated from the DevSecOps section of the platform.
- GitHub Actions enabled on the repository.
- A Linux runner (
ubuntu-latestor equivalent) — the action requires Docker, which is only available on Linux-hosted runners. - The step runs directly on the runner, not inside a job container (
jobs.<job_id>.container), because the action mounts the workspace into its own container.
The action runs the Fluid Attacks CI Gate (ghcr.io/fluidattacks/forces:latest) as a Docker container. The gate authenticates with the Fluid Attacks platform using the CI Gate token, retrieves the vulnerability findings already reported for the specified repository, and evaluates them against your group's security policies.
In lax mode (default), the job passes even when vulnerabilities break policy, and vulnerabilities_found tells you whether they did. In strict mode, the job fails with exit code 66 when they do. In both modes, the job fails if the gate itself cannot finish, for example because the token is invalid.
The container runs in the job workspace, mounted read-only. If the workflow checks out the repository before this step, the gate reads the commit, branch and origin from Git. Otherwise, it takes the commit and branch from GitHub (GITHUB_SHA and GITHUB_REF_NAME). The gate needs no Git credentials, so set persist-credentials: false on actions/checkout. With pull_request_target, keep the checkout on its default ref, the base branch, and do not check out the pull request's code.
| Input | Required | Default | Description |
|---|---|---|---|
api_token |
Yes | — | CI Gate token for authenticating with the Fluid Attacks platform. Use a secret: ${{ secrets.FA_API_TOKEN }}. |
repo_name |
No | GitHub repo name | Repository nickname as configured in the Fluid Attacks platform. When not set, defaults to the GitHub repository name (GITHUB_REPOSITORY minus the owner prefix). |
strict |
No | false |
Set to true to enable strict mode. The job fails if open or untreated vulnerabilities that break policy are found. |
report_output_path |
No | — | Path relative to the workspace root where the JSON report will be saved. It must stay inside the workspace. If not set, the report is not saved in the workspace. |
| Output | Description |
|---|---|
vulnerabilities_found |
true if policy-breaking vulnerabilities were found, in lax or strict mode, false otherwise. Not set when the gate itself fails. |
report_output_path |
Path to the JSON report file. Only set when the report_output_path input is configured. |
You can use these outputs in subsequent workflow steps:
- name: Print result
if: steps.gate.outputs.vulnerabilities_found == 'true'
run: echo "Open vulnerabilities found. Review them on the Fluid Attacks platform."Set strict: true to make the job fail when policy-breaking vulnerabilities are found. Combined with branch protection rules, this prevents vulnerable code from being merged:
- uses: fluidattacks/ci-gate-action@<version>
with:
api_token: ${{ secrets.FA_API_TOKEN }}
repo_name: my-repo
strict: trueThen, in your repository settings, enable Require status checks to pass before merging and select the CI Gate check.
Use report_output_path to write the full report to a file, then upload it as a workflow artifact:
- uses: fluidattacks/ci-gate-action@<version>
id: gate
with:
api_token: ${{ secrets.FA_API_TOKEN }}
repo_name: my-repo
report_output_path: fa-report.json
- name: Upload report
if: always()
uses: actions/upload-artifact@v4
with:
name: fluid-attacks-report
path: ${{ steps.gate.outputs.report_output_path }}Run in lax mode but fail the job manually based on the output:
- uses: fluidattacks/ci-gate-action@<version>
id: gate
with:
api_token: ${{ secrets.FA_API_TOKEN }}
repo_name: my-repo
- name: Fail if vulnerabilities found
if: steps.gate.outputs.vulnerabilities_found == 'true'
run: exit 1Verify that your CI Gate token is correct and has not expired. Tokens are valid for 180 days. To renew it, go to Organization → Groups → GroupName → DevSecOps in the platform and click Manage token. Update the FA_API_TOKEN secret in your repository with the new token.
Ensure that repo_name matches the nickname registered in the Fluid Attacks platform exactly. When repo_name is not set, the action derives it from the GitHub repository name, which may differ from the nickname on the platform. Set repo_name explicitly to resolve the mismatch.
Confirm that the repo_name input matches the repository nickname configured in the Fluid Attacks platform exactly. A mismatch causes the action to query the wrong repository and return no findings.
If strict: true is set, the job fails with exit code 66 whenever policy-breaking vulnerabilities are found. This is intentional. Set strict: false if you want the check to report results without failing the pipeline.
Any other non-zero exit code means the check did not finish, and the log shows the reason as an error. CI Gate failed with exit code followed by the code comes from the gate: check the token, the repo_name input and the network access to the Fluid Attacks platform. Exit code 2 with must be a single line or must be a file path inside the workspace points to the repo_name or report_output_path inputs.
The action requires Docker. Docker is only available on Linux-hosted runners. Make sure your workflow uses runs-on: ubuntu-latest or another Linux runner.