Skip to main content

Sync inventory from your pipeline

Cloud has no built-in auto-sync. Your pipeline must call POST /api/v1/integrations/{provider}/scan, then POST /api/v1/integrations/import to update inventory. The auto-sync /run endpoint is unavailable in Cloud.

Session prerequisite

Cloud supports password login through the API without an initial CAPTCHA. After three failed password logins within 15 minutes for either the account or client IP, login returns 403 RECAPTCHA_REQUIRED with Retry-After; stop the job and complete browser verification or wait before retrying. Existing rate limits and 2FA still apply. Sessions expire after two hours of inactivity; authenticate at the start of each job. ttx_ tokens cannot authenticate integration calls.

Before running​

  • Start each job with the API login recipe for a manager/admin account. Select the workspace UUID and your Cloud origin. The example below reads these from WORKSPACE_ID and BASE, with the login recipe's private cookie file in COOKIE_JAR.
  • Supply provider credentials from your pipeline's secret store on every run; Cloud never retains them. Follow the provider's credential setup. Actual visibility depends on the provider account's permissions.
  • Serialize runs per workspace/provider account within your scan quota. Disable shell tracing and remove cookies when the job ends.

Supported scan filters​

The fields below belong in the scan request's JSON body. These are API defaults; dashboard presets can differ. All providers also accept filterRules for include/exclude matching. Except for Vault, maxItems defaults to 500 and accepts 1–2000. A limit bounds results; it is not pagination. Review incomplete/truncated results before importing.

HashiCorp Vault (vault)​

FieldSupported selection / default
include.kv, include.pkiScan KV v2 secrets and/or PKI certificates; both default to true.
mountsArray of mount paths; omitted means all supported mounts.
pathPrefixRestrict KV v2 paths under a mount; PKI scans ignore this field. Omitted means no prefix restriction.
categoriesArray containing cert and/or key_secret; omitted or empty means both.
maxItemsPerMountPer-mount budget; default 250, capped at 2000.

GitLab (gitlab)​

FieldSupported selection / default
include.tokens, include.keysEnable token and SSH-key scans; both default to true.
filters.includePATsPersonal access tokens; default true.
filters.includeProjectTokens, filters.includeGroupTokensProject/group access tokens; both default to true.
filters.includeDeployTokensDeploy tokens; default true.
filters.includeTriggerTokensPipeline trigger tokens; default false.
filters.includeSSHKeysUser SSH keys, also requiring include.keys; default true.
filters.includeExpired, filters.includeRevokedInclude expired/revoked tokens where the provider exposes them; both default to false.
filters.excludeUserPATsExclude regular-user PATs while retaining administrator/service-account PATs; default false.

GitHub (github)​

FieldSupported selection / default
include.secretsRepository Actions secrets; default true.
include.sshKeys, include.deployKeysUser SSH keys and repository deploy keys; both default to true.
include.tokensDefault true, but GitHub PATs cannot be enumerated; this adds an informational summary only. Set false when checking every summary entry for completeness.
include.keysLegacy fallback for sshKeys and deployKeys when those fields are omitted.

AWS (aws)​

FieldSupported selection / default
include.secrets, include.iam, include.certificatesSecrets Manager, IAM access keys and ACM certificates; all default to true.
regionSingle-region scan; default us-east-1. IAM is global.
scanMode, regionsSet scanMode: "all-regions" and supply a regions array to sweep the selected regions. Omitted/empty regions does not discover regions automatically.

Azure Key Vault (azure)​

FieldSupported selection / default
include.secrets, include.certificates, include.keysSecrets, certificates and cryptographic keys; all default to true.

Microsoft Entra ID (azure-ad)​

FieldSupported selection / default
include.applications, include.servicePrincipalsApplication and service-principal credentials; both default to true.

Google Cloud (gcp)​

FieldSupported selection / default
include.secretsSecret Manager secrets; default true.
include.certificatesCertificate Manager and Compute Engine SSL certificates; default false.

GitLab example: scan and import​

This example uses Bash, curl, jq, and a secret-store GITLAB_SCAN_TOKEN with GitLab permissions. It uses the API's default scan selections and leaves cleanup off. For another provider, change the scan path, credentials and request body; retain items and scan_id for the shared import endpoint, and adapt completeness checks to that provider's response.

set +x
set -euo pipefail
umask 077
: "${COOKIE_JAR:?}" "${WORKSPACE_ID:?}" "${GITLAB_SCAN_TOKEN:?}"
export GITLAB_SCAN_TOKEN
BASE=${BASE:-https://tokentimer.ch}
test -r "$COOKIE_JAR"
WORK=$(mktemp -d)
trap 'rm -rf "$WORK"' EXIT

curl --fail-with-body -sS -b "$COOKIE_JAR" "$BASE/api/session" \
| jq -e '.loggedIn == true' >/dev/null
CSRF=$(curl --fail-with-body -sS -b "$COOKIE_JAR" -c "$COOKIE_JAR" \
"$BASE/api/csrf-token" | jq -er '.csrfToken')

# Credentials go in the request body; do not print it or upload it as an artifact.
jq -n '{baseUrl: "https://gitlab.com", token: env.GITLAB_SCAN_TOKEN,
maxItems: 500}' >"$WORK/request.json"
curl --fail-with-body -sS -b "$COOKIE_JAR" -c "$COOKIE_JAR" -X POST \
"$BASE/api/v1/integrations/gitlab/scan?workspace_id=$WORKSPACE_ID" \
-H "X-CSRF-Token: $CSRF" -H 'Content-Type: application/json' \
--data-binary @"$WORK/request.json" >"$WORK/scan.json"

# Stop when any selected scope reports an incomplete scan.
jq -e '(.scan_id | type == "string" and length > 0) and (.items | type == "array")
and (.summary | length > 0)
and all(.summary[]; .complete == true)' "$WORK/scan.json" >/dev/null
if jq -e '.items | length == 0' "$WORK/scan.json" >/dev/null; then
echo 'Scan complete; no items to import.'
exit 0
fi

# Preserve the returned items and scan_id so imports retain source attribution.
jq '{items, scan_id, cleanup: {enabled: false}}' "$WORK/scan.json" >"$WORK/import.json"
curl --fail-with-body -sS -b "$COOKIE_JAR" -c "$COOKIE_JAR" -X POST \
"$BASE/api/v1/integrations/import?workspace_id=$WORKSPACE_ID" \
-H "X-CSRF-Token: $CSRF" -H 'Content-Type: application/json' \
--data-binary @"$WORK/import.json" >"$WORK/result.json"
jq '{created_count, updated_count, error_count, deleted_count}' "$WORK/result.json"
jq -e '.error_count == 0 and .deleted_count == 0' "$WORK/result.json" >/dev/null

Verify and operate​

HTTP 201 can include partial success: inspect error_count and errors. New items consume token capacity; if a batch exceeds it, successful items remain imported. Resolve the capacity or item errors before retrying. Verify inventory source/expiry and updates on subsequent runs. Alert on failure, renew expired sessions, and honor Retry-After on HTTP 429.

Completeness describes the selected scopes visible to your credentials; it is not an audit of provider permissions or a guarantee that the provider exposes every credential. GitLab permission errors mark the affected scope incomplete. Review the provider's access requirements before relying on a pipeline's inventory.

Cleanup is off by default. Before enabling irreversible deletion, review cleanup behavior and the import schema. Each cleanup attempt needs a fresh scan.