Bitbucket
Discover AI assets in your Bitbucket repositories with the Airia Code Scanner.
Airia discovers AI assets living in your Bitbucket Cloud repositories: agent frameworks, model SDK usage, prompt files, workflow definitions, MCP server configurations, and hard-coded LLM keys or endpoints.
Status
The Bitbucket connector is released behind a feature flag, so it may not be enabled for your tenant yet. If the Bitbucket tile is not visible under Discover → Connections, ask your Airia contact to enable it. Ingestion is not gated: once a pipeline is configured, scans are accepted and appear in the inventory regardless of the flag.
How Bitbucket discovery works
Bitbucket discovery is powered by the Airia Code Scanner, which runs as a Bitbucket Pipelines step inside your repository. Each scan analyzes the repository's contents and reports its findings to your Airia tenant; every scanned repository then appears as a Bitbucket connection under Discover → Connections, with the discovered code-based agents in the inventory.
There is no credential form to fill in on the Airia side, and Airia never connects to Bitbucket: the scanner authenticates to Airia with an API key you store as a repository variable, and pushes results outward.
The step runs the scanner image directly as its image:, so it needs no Docker service.
What the scanner detects
| Category | Indicators |
|---|---|
| Agent frameworks | CrewAI, LangGraph, LangChain, and similar framework usage and agent definitions |
| Model SDK usage | Imports and dependencies such as openai, anthropic, azure-ai, google-genai in requirements.txt, package.json, pom.xml, and similar |
| Prompt files | Standalone prompt assets and templates (*.prompt, prompts/ directories, system-prompt strings) |
| LLM keys and endpoints in config | Model API keys and endpoint URLs in .env, config files, or infrastructure-as-code (a security finding as well as an inventory signal) |
| Model artifacts | Model files and references (including hosted model references such as Hugging Face) |
| Workflow files | n8n workflow exports, LangGraph graph definitions, and similar agentic workflow files |
| MCP server configs | Model Context Protocol server manifests and client configurations (for example mcp.json) |
Customer-side setup steps
-
Generate an Airia API key. In Airia: Settings → API Keys → Generate Key. Name it something like
code-scanner-bitbucket, leave the scope at its default, and copy the value — it is shown once. -
Enable Pipelines. In the Bitbucket repository: Repository settings → Pipelines → Settings → Enable Pipelines. Pipelines is off by default, and a committed
bitbucket-pipelines.ymldoes nothing until it is on. -
Add two repository variables. Repository settings → Pipelines → Repository variables.
Name Value Flags AIRIA_API_URLyour Airia API URL, for example https://api.airia.aion Airia's US cloud (use your instance's API URL on another region or a self-managed instance), with no path and no trailing/— AIRIA_API_TOKENthe API key from step 1 Secured To scan several repositories, add the same two variables once as workspace variables (Workspace settings → Pipelines → Workspace variables) instead of per repository. A repository variable overrides a workspace variable with the same name.
-
Add the pipeline file. Create
bitbucket-pipelines.ymlat the repository root, or merge the step definition and pipelines into an existing one. Replacemainunderbranches:with your default branch.# Airia Code Scanner definitions: steps: - step: &airia-code-scan name: Airia Code Scan # The scanner image is the build container: no Docker service needed. image: airiadevops305/airia-code-scanner:latest script: - export PROVIDER="Bitbucket" - export REPOSITORY_OWNER="$BITBUCKET_WORKSPACE" - export REPOSITORY="$BITBUCKET_REPO_SLUG" # BITBUCKET_GIT_HTTP_ORIGIN is http://, so the URL is built explicitly. - export REPOSITORY_URL="https://bitbucket.org/$BITBUCKET_REPO_FULL_NAME" - export BRANCH="$BITBUCKET_BRANCH" - export COMMIT_SHA="$BITBUCKET_COMMIT" # AIRIA_API_URL and AIRIA_API_TOKEN come from the repository variables # added in step 2. A trailing slash would break the webhook path. - export AIRIA_API_URL="${AIRIA_API_URL%/}" # Bitbucket clones into .../agent/build, and the scanner skips any path # containing a "build" directory, so it scans a copy of the checkout. - cp -a "$BITBUCKET_CLONE_DIR" /tmp/src - export GITHUB_WORKSPACE=/tmp/src - /app/scanner-cli || rc=$? # Step artifacts are collected from the clone dir. - cp /tmp/src/scan-results.json "$BITBUCKET_CLONE_DIR/" || true - exit ${rc:-0} artifacts: - scan-results.json pipelines: branches: # Replace main with your default branch. main: - step: *airia-code-scan pull-requests: '**': - step: *airia-code-scan custom: # Run by hand from Pipelines > Run pipeline, or from a schedule. airia-code-scan: - step: *airia-code-scan -
Run the pipeline. Pushing the file to the default branch triggers it. To start one by hand: Pipelines → Run pipeline, pick the branch and the
custom: airia-code-scanpipeline. -
Verify. Open the Airia Code Scan step log; the scanner prints the repository, branch, commit and workspace it used, and finishes with
Successfully reported findings to API (status: 200). Thescan-results.jsonartifact is exactly what was sent, which separates a scanning problem from a delivery one.Read the step's status with two caveats:
- A failed step can still have delivered its results. The scanner exits with an error when
it finds a Critical issue, such as a hard-coded API key, so the pipeline blocks on it.
It reports to Airia before exiting, so the findings are in Airia either way; the log shows
SCAN FAILED: Found N critical security issues. - A passed step does not prove delivery. If the report to Airia fails, the scanner logs
Failed to report findingsorError reporting to APIand the step still passes. Only theSuccessfully reported findings to APIline confirms the results arrived. AnError reporting to APIline that mentions a connection or name-resolution failure meansAIRIA_API_URLpoints at the wrong host.
Then in Airia open Discover → Connections → Bitbucket: the scanned repository appears as a connection, and its discovered agents land in the inventory with their detected frameworks and model references.
- A failed step can still have delivered its results. The scanner exits with an error when
it finds a Critical issue, such as a hard-coded API key, so the pipeline blocks on it.
It reports to Airia before exiting, so the findings are in Airia either way; the log shows
Notes
- The pipeline scans a copy of the checkout at
/tmp/src. The scanner reads the checkout fromGITHUB_WORKSPACE, a name it kept from its GitHub Actions origins, and skips directories such asbuild. Bitbucket clones into/opt/atlassian/pipelines/agent/build, so the template copies the checkout out of it, and copiesscan-results.jsonback so the step artifact still works. WithoutGITHUB_WORKSPACEset, the scanner finds nothing and the scan succeeds with zero findings. REPOSITORY_URLis built explicitly becauseBITBUCKET_GIT_HTTP_ORIGINis anhttp://URL. Findings deep-link tobitbucket.org/{workspace}/{repo}/src/{commit}/{path}#lines-{n}.- Bitbucket Cloud only. Bitbucket Data Center has no Pipelines; run the scanner from your CI of choice as described in Airia Code Scanner.
- Every scan consumes build minutes from the workspace plan. To scan only when relevant files
change, merge a
condition: changesets: includePaths:onto the step; for large repositories, run the custom pipeline from a schedule (Pipelines → Schedules) instead of on every push. - One connection appears per scanned repository and branch; multiple repositories mean multiple connections.
Repositories hosted elsewhere are covered by the GitHub, Azure DevOps and GitLab connectors, which use the same scanner and the same push model.