Automated Compliance Testing
Integrate Tork SDK verification into your CI/CD pipelines to ensure continuous compliance and catch issues before they reach production.
Why CI/CD Integration?
Prevent Regressions
Catch compliance issues in pull requests before they merge to main.
Continuous Monitoring
Run daily verification checks to maintain compliance over time.
Fast Feedback
Get immediate feedback on your verification score with every commit.
Quick Setup
- 1
Add your API key as a secret
Store
TORK_API_KEYin your CI/CD platform's secret management. - 2
Copy the configuration for your platform
Use one of the examples below for GitHub Actions, GitLab CI, Jenkins, or others.
- 3
Customize thresholds and notifications
Set your minimum score threshold and configure notifications for failures.
What the pipeline install does and does not do
pip install tork-governance installs the on-device package. tork-governance makes the governance decision on your machine. PII detection, redaction and the returned verdict are computed on-device. With no API key it makes zero network calls: prompts, completions and detected PII values never leave the machine, and nothing appears in your dashboard.
The score and certificate these pipelines produce do not come from that package. They come from the verification REST API, which the script below calls with your TORK_API_KEY. The package is installed so the script can report the exact SDK version under test.
Supply an API key and the SDK additionally reports a metadata-only attestation of each decision — the action taken, PII type labels and counts, a risk classification, policy labels and a salted fingerprint. It never sends input text, output text or PII values. The decision itself is still made on-device and is never delayed or changed by reporting. Those attestations appear in your dashboard and are included in the daily on-chain anchor — each one recorded as a client attestation (capture_mode=edge, attested_by=client), a claim Tork recorded but did not execute and cannot independently verify. Requires tork-governance 0.24.0+ (PyPI) or 0.11.0+ (npm).
A decision reported by an on-device SDK is recorded as a client attestation (capture_mode=edge, attested_by=client): a claim Tork recorded but did not execute and cannot independently verify. A decision made by @torknetwork/sdk is recorded as capture_mode=cloud, attested_by=tork — Tork made that call itself. Both are equally immutable once anchored; they differ in what is immutable. A client attestation freezes your claim. A server-governed receipt freezes Tork's own decision.
GitHub Actions
The most comprehensive integration with PR comments and artifacts.
# .github/workflows/tork-verify.yml
name: Tork SDK Verification
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
schedule:
- cron: '0 0 * * *' # Daily at midnight
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install tork-governance pytest httpx
- name: Run Tork Verification
env:
TORK_API_KEY: ${{ secrets.TORK_API_KEY }}
run: |
python tork_verify.py
python -c "
import json, sys
cert = json.load(open('verification-result.json'))['certification']
print(f\"Score: {cert['score']}/100\")
print(f\"Grade: {cert['grade']}\")
print(f\"Report: {cert['report_url']}\")
if cert['score'] < 80:
print('::error::Verification score below threshold')
sys.exit(1)
"
- name: Upload Results
uses: actions/upload-artifact@v4
with:
name: tork-verification
path: verification-result.json
- name: Comment on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const { certification } = JSON.parse(fs.readFileSync('verification-result.json'));
const emoji = certification.score >= 80 ? '✅' : certification.score >= 60 ? '⚠️' : '❌';
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## ${emoji} Tork Verification Results
| Metric | Value |
|--------|-------|
| Score | **${certification.score}/100** |
| Grade | **${certification.grade}** |
| Tests | ${certification.passed_tests}/${certification.total_tests} passed |
[View Full Report](https://tork.network${certification.report_url})
`
});GitLab CI
Native GitLab CI/CD integration with artifacts and merge request rules.
# .gitlab-ci.yml
stages:
- test
- verify
tork-verification:
stage: verify
image: python:3.11
variables:
TORK_API_KEY: $TORK_API_KEY
script:
- pip install tork-governance httpx
- python tork_verify.py
- |
python << 'EOF'
import json
import sys
cert = json.load(open("verification.json"))["certification"]
print(f"Score: {cert['score']}/100")
print(f"Grade: {cert['grade']}")
if cert["score"] < 80:
sys.exit(1)
EOF
artifacts:
paths:
- verification.json
reports:
dotenv: tork-results.env
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCHJenkins
Declarative pipeline with email notifications on failure.
// Jenkinsfile
pipeline {
agent any
environment {
TORK_API_KEY = credentials('tork-api-key')
}
stages {
stage('Verify Tork Integration') {
steps {
sh '''
pip install tork-governance httpx
python tork_verify.py
python - <<'PY'
import json
import sys
cert = json.load(open("verification.json"))["certification"]
print("Score: {}/100".format(cert["score"]))
print("Grade: {}".format(cert["grade"]))
sys.exit(0 if cert["score"] >= 80 else 1)
PY
'''
}
post {
always {
archiveArtifacts artifacts: 'verification.json'
}
failure {
emailext(
subject: 'Tork Verification Failed',
body: 'Score dropped below threshold. Check Jenkins for details.',
to: '${DEFAULT_RECIPIENTS}'
)
}
}
}
}
}CircleCI
CircleCI workflow with context-based credentials.
# .circleci/config.yml
version: 2.1
orbs:
python: circleci/python@2.1
jobs:
tork-verify:
executor: python/default
steps:
- checkout
- run:
name: Install Tork SDK
command: pip install tork-governance httpx
- run:
name: Run Verification
command: |
python tork_verify.py
python << 'EOF'
import json
import sys
cert = json.load(open("verification.json"))["certification"]
print(f"Score: {cert['score']}/100")
print(f"Grade: {cert['grade']}")
if cert["score"] < 80:
sys.exit(1)
EOF
- store_artifacts:
path: verification.json
destination: tork-verification
workflows:
verify:
jobs:
- tork-verify:
context: tork-credentialsBitbucket Pipelines
Bitbucket Pipelines with PR-specific verification.
# bitbucket-pipelines.yml
image: python:3.11
pipelines:
default:
- step:
name: Tork Verification
script:
- pip install tork-governance httpx
- python tork_verify.py
- |
python << 'EOF'
import json
import sys
cert = json.load(open("verification.json"))["certification"]
print(f"Score: {cert['score']}/100")
print(f"Grade: {cert['grade']}")
sys.exit(0 if cert["score"] >= 80 else 1)
EOF
artifacts:
- verification.json
pull-requests:
'**':
- step:
name: Verify on PR
script:
- pip install tork-governance httpx
- python tork_verify.py --min-score 80Best Practices
Set appropriate thresholds
Start with a threshold of 80 and increase as your integration matures. Use different thresholds for PRs vs. main branch.
Run on schedule, not just on push
Schedule daily runs to catch issues with external dependencies or API changes that might affect your score.
Save verification artifacts
Always save the full verification result as an artifact for debugging and compliance audits.
Don't fail silently
Configure notifications for verification failures. Use Slack, email, or your team's preferred channel.
The tork_verify.py Script
The pipelines above call a small script you commit to your repository. It drives the verification REST API — register a session, submit results, request certification — and writes verification.json for the pipeline to read. See Testing Suite for the full endpoint reference and the list of required tests per SDK.
import argparse
import json
import os
import platform
import sys
import httpx
from tork_governance import __version__
API_BASE = "https://tork.network"
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--min-score", type=int, default=80)
parser.add_argument("--save", default="verification.json")
args = parser.parse_args()
api_key = os.environ["TORK_API_KEY"]
# 1. Register a test session
session = httpx.post(
f"{API_BASE}/api/v1/testing/register",
json={
"api_key": api_key,
"client_id": f"ci-{platform.node()}",
"sdk_type": "python",
"sdk_version": __version__,
"platform": {
"os": platform.system().lower(),
"arch": platform.machine(),
"runtime_version": platform.python_version(),
},
},
timeout=30,
).raise_for_status().json()
session_id = session["session_id"]
test_token = session["test_token"]
# 2. Run the required tests locally and submit the results
results = [run_test(*t.split(".")) for t in session["test_config"]["required_tests"]]
httpx.post(
f"{API_BASE}/api/v1/testing/submit",
json={
"session_id": session_id,
"test_token": test_token,
"results": results,
"complete": True,
},
timeout=30,
).raise_for_status()
# 3. Request certification
cert = httpx.post(
f"{API_BASE}/api/v1/testing/certify",
json={"session_id": session_id, "test_token": test_token},
timeout=30,
).raise_for_status().json()
with open(args.save, "w") as f:
json.dump(cert, f, indent=2)
score = cert["certification"]["score"]
print(f"Score: {score}/100 Grade: {cert['certification']['grade']}")
return 0 if score >= args.min_score else 1
if __name__ == "__main__":
sys.exit(main())Need Help?
Our team is here to help you set up CI/CD integration. Reach out if you need assistance with custom configurations or enterprise deployments.

