Client Onboarding Guide¶
End-to-end process for activating a new CI/CD code review client, from first contact to production deployment.
Onboarding Flow¶
graph TB
A["1. Client Interest<br/>(demo / referral)"] --> B["2. Plan Selection<br/>(Essentials / Pro / Enterprise)"]
B --> C["3. Company Setup<br/>(dashboard)"]
C --> D["4. API Key Generation<br/>(admin)"]
D --> E["5. Client Receives Key<br/>(secure channel)"]
E --> F["6. CI Pipeline Setup<br/>(client repo, 5 min)"]
F --> G["7. First Scan Verification<br/>(test PR)"]
G --> H["8. Production<br/>(ongoing monitoring)"]
style A fill:#4a148c,color:#fff
style B fill:#6a1b9a,color:#fff
style C fill:#7b1fa2,color:#fff
style D fill:#8e24aa,color:#fff
style E fill:#0277bd,color:#fff
style F fill:#00838f,color:#fff
style G fill:#00695c,color:#fff
style H fill:#2e7d32,color:#fff
Step 1: Client Assessment¶
Before activating, gather basic information:
| Question | Why It Matters |
|---|---|
| Primary languages? | Determines which SAST tools are most relevant |
| CI/CD provider? | GitHub Actions, GitLab CI, or Azure DevOps |
| Number of repos? | Determines plan pricing |
| PR volume per month? | Ensures scan limit is adequate |
| Existing pentest engagement? | Bundle discount opportunity |
| Compliance requirements? | May need strict quality gate preset |
Qualification Checklist¶
- [ ] Client uses a supported CI provider (GitHub / GitLab / Azure)
- [ ] Client has at least one active repository
- [ ] Client can store secrets in CI/CD configuration
- [ ] Client contact has permission to modify CI pipelines
Step 2: Plan Selection¶
Present the three tiers based on client needs:
| Need | Recommended Plan | Price |
|---|---|---|
| Basic SAST scanning, vulnerability awareness | Essentials | EUR 49/repo/month |
| Deep analysis with AI remediation advice | Professional | EUR 149/repo/month |
| Large organization, multiple repos, dual-engine | Enterprise | Custom |
| Already has pentest engagement | Bundle | EUR 99/repo/month |
Decision Guide¶
Does the client need AI-powered remediation?
No -> Essentials (EUR 49)
Yes -> Does the client have > 5 repos?
Yes -> Enterprise (custom quote)
No -> Does the client also have a pentest engagement?
Yes -> Bundle (EUR 99)
No -> Professional (EUR 149)
Step 3: Company Setup¶
If the client already has a BeDefended dashboard account:
- Verify the company exists in the dashboard
- Note the
company_id
If the client is new:
- Create company in the dashboard (admin portal)
- Set up client portal access for the client's technical contact
- Assign the appropriate pentest plan (if bundling)
Step 4: API Key Generation¶
Admin Only
API key generation requires admin access to the dashboard.
Via Dashboard API¶
curl -X POST https://your-dashboard.bedefended.com/api/v1/ci/api-keys \
-H "Authorization: Bearer $ADMIN_JWT" \
-H "Content-Type: application/json" \
-d '{
"company_id": 1,
"repo_pattern": "acme/*",
"tier": "professional",
"monthly_scan_limit": 2000
}'
Response:
{
"api_key": "bd_sk_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"key_prefix": "bd_sk_a1b2c3...",
"tier": "professional",
"repo_pattern": "acme/*",
"monthly_scan_limit": 2000
}
One-Time Display
The full API key is only shown at creation. Copy it immediately. Only the prefix (bd_sk_a1b2c3...) is stored visibly. The key is stored as a SHA-256 hash in the database.
Key Configuration¶
| Field | Guidance |
|---|---|
repo_pattern |
org/repo for single repo, org/* for all repos in an org |
tier |
Must match the client's subscription |
monthly_scan_limit |
500 for Essentials, 2000 for Professional, 999999 for Enterprise |
Step 5: Deliver Key to Client¶
Send the API key to the client's technical contact via a secure channel:
- Preferred: 1Password / Bitwarden shared vault
- Alternative: Encrypted email or secure messaging
- Never: Plain email, Slack, or any unencrypted channel
Client Email Template¶
Subject: BeDefended CI/CD Code Review - Setup Instructions
Hi [Name],
Your BeDefended CI/CD Code Review is ready. Here's everything you need:
Plan: [Professional / Essentials / Enterprise]
API Key: [delivered separately via secure channel]
Scan Limit: [500 / 2000 / unlimited] scans/month
Setup (5 minutes):
1. Store the API key as a secret in your CI/CD:
- GitHub: Settings > Secrets > Actions > BD_API_KEY
- GitLab: Settings > CI/CD > Variables > BD_API_KEY (masked)
- Azure: Pipeline > Variables > BD_API_KEY (secret)
2. Add the workflow file to your repo:
[Attach the appropriate template from ci/examples/]
3. Open a test PR to verify everything works.
Documentation: https://redpick-docs.pages.dev/ci-cd/
Support: support@bedefended.com
Best,
[Your name]
BeDefended
Step 6: Client Pipeline Setup¶
Guide the client through CI setup. The process takes approximately 5 minutes.
- Store
BD_API_KEYin repository secrets - Copy the workflow file to
.github/workflows/code-review.yml - (Optional) Create
.bedefended.ymlfor custom configuration - Push to trigger the first run
- Store
BD_API_KEYas a masked CI/CD variable - Add the
includedirective to.gitlab-ci.yml - (Optional) Create
.bedefended.yml - Create a merge request to trigger
- Store
BD_API_KEYas a secret pipeline variable - Create a GitHub service connection for template reference
- Create
azure-pipelines.ymlwith the template reference - Create a pull request to trigger
Verification Checklist¶
After the first scan, verify with the client:
- [ ] CI pipeline ran successfully
- [ ] SAST findings appear in the pipeline logs
- [ ] SARIF uploaded to Security tab (GitHub) / Code Quality widget (GitLab)
- [ ] PR comments appear inline at the correct lines
- [ ] Quality gate passed or failed as expected
- [ ] Scan count incremented in usage dashboard
Step 7: First Scan Review¶
Schedule a 15-minute call with the client to review the first scan results:
- Walk through any findings together
- Adjust quality gate thresholds if needed
- Add exclusion paths for false positive sources (tests, vendors)
- Confirm the tier meets their needs (upgrade if AI analysis would help)
Common Adjustments¶
| Client Feedback | Action |
|---|---|
| "Too many findings in test files" | Add tests/** to quality-gate.ignore-paths |
| "We don't use Ruby" | Leave as-is (brakeman auto-skips if no Gemfile) |
| "Can we fail on medium too?" | Switch to strict preset or --fail-on medium |
| "We want AI analysis" | Upgrade to Professional tier |
| "Scans take too long" | Use mode: diff to only scan changed files |
Step 8: Ongoing Operations¶
Monthly Tasks¶
- Review usage dashboard (
GET /api/v1/ci/usage/{company_id}) - Verify scan counts are within plan limits
- Monthly scan counters auto-reset on the 1st
Client Self-Service¶
Clients can independently:
- Modify
.bedefended.ymlin their repo - Change quality gate thresholds
- Add/remove exclusion paths
- Switch between
diffandfullscan modes
Escalation Path¶
| Issue | Resolution |
|---|---|
| API key compromised | Deactivate old key, generate new one |
| Scan limit exceeded | Upgrade plan or wait for monthly reset |
| False positive volume high | Tune semgrep rules, add ignore paths |
| Client wants pentest too | Offer bundle discount |
Bundle Upsell Opportunity¶
When a client has CI/CD active and hasn't done a pentest:
"Your CI/CD code review found [N] high-severity findings this month. A blackbox pentest would verify which of these are exploitable in production and catch logic bugs that static analysis can't find. With the bundle, the CI/CD tier drops from EUR 149 to EUR 99/month."
When a pentest client doesn't have CI/CD:
"During the pentest we found [N] vulnerabilities that a CI/CD code review would catch before they reach production. Setting up takes 5 minutes and ensures these classes of bugs never make it to deployment again."
Troubleshooting¶
"Invalid API key" (401)¶
- Verify the key is stored correctly in CI secrets (no trailing whitespace)
- Check the key hasn't expired
- Verify the key is active in the dashboard
"Monthly scan limit exceeded" (429)¶
- Check current usage via the admin dashboard
- Upgrade the plan or wait for the monthly reset
"No findings"¶
- Verify SAST tools ran (check CI logs for tool output)
- Check
.bedefended.ymlisn't excluding all files - Try
mode: fullinstead ofdifffor the first run
Docker image pull failures¶
- Verify
ghcr.io/bedefended/bd-sast:latestis accessible - For private registries, authenticate with
docker login ghcr.io - Use a specific tag instead of
latestfor reproducibility