personio-security
Your security workflow companion — Semgrep scans behind the scenes as you write, walks you through fixing findings from the developer portal, and ships fixes as PRs. So engineers can focus on shipping, not on chasing dashboards.
Installation
# Org-wide marketplace (recommended — everyone in PTech has this configured):
/plugin install personio-security@personio-claude-code-marketplace
# Security-team catalog (the source-of-truth dev catalog):
/plugin install personio-security@sec-claude-code-configuration
After installing, run the one-time setup:
/setup-semgrep-cli
What does this plugin do?
Security tooling and knowledge for Personio engineers, surfaced as Claude Code skills. So you can handle security work — running scans, fixing findings, learning what good looks like — without leaving your editor.
Two security checkpoints, each saving you a manual step:
- Before you PR —
/semgrep-scanscans your local changes to flag security issues (SAST, SCA, and hardcoded secrets) before you push your changes upstream. - From the developer portal —
/fix-developer-portal-sec-findingspulls your repo's open findings and walks you through them end-to-end, finishing with an opened PR.
/setup-semgrep-cli
One-time installer for the Semgrep CLI, Pro engine, and Personio org login. Claude checks what's already there and only runs the steps you actually need.
What you need:
- macOS with Homebrew (or any system where
semgrepcan be installed) - A Personio Semgrep account (SSO)
Quick Start:
/setup-semgrep-cli
Example:
/setup-semgrep-cli
→ Checking your setup…
✅ Semgrep CLI 1.152.0 already installed
✅ Logged in as you@personio.de (deployment: personio-prod)
✅ Semgrep Pro engine installed
You're all set. /semgrep-scan is ready when you want a scan.
Why would you want this? You just installed the plugin and want a single guided run that gets every prerequisite working. Run it again any time you need to reinstall or re-authenticate Semgrep.
/semgrep-scan
Run a Semgrep scan over your local changes (or a path, or the whole repo). Findings come back grouped by severity, with concrete fixes you can review before Claude applies them. Never blocks anything — you decide what to fix.
What you need:
/setup-semgrep-clicompleted- Logged into Personio's Semgrep org
Quick Start:
# Default: scan your local changes (diff against HEAD)
/semgrep-scan
# Or scope to a path
/semgrep-scan ./src/auth
Example:
/semgrep-scan
→ Found 2 modified files — scanning the diff against HEAD.
This usually takes 3–5 minutes.
⏳ Running semgrep ci --dry-run --baseline-commit HEAD …
## High (1)
[High] python.flask.os.tainted-os-command
File: services/users.py:23
CWE: CWE-78: OS Command Injection
Code: os.system(f"useradd {username}")
Fix: subprocess.run(['useradd', username], check=True)
Summary: 1 finding (1 High) across 1 file.
→ Should I apply the fix?
You: yes
✅ Fix applied. Re-scan clean.
Why would you want this?
- Recommended before committing or pushing your changes — a full security analysis of what you're about to send upstream.
- Flags SAST, SCA, and hardcoded-secret issues in your local changes so you can fix them early.
- Findings are presented in a format Claude can actually act on — no scrolling through raw output.
- The scan stays local (
--dry-run) and does not pollute the dashboard.
Trade-off worth knowing: Wait time scales with scope and product set:
- Diff or path-scoped, single product (e.g.
--baseline-commit HEAD --supply-chain) — typically 3–5 minutes. The default for pre-commit / pre-PR use. - Diff or path-scoped, all products — 5–10 minutes. The default when you don't pass a product flag.
- Full-repo, single product — 10–20 minutes depending on repo size.
- Full-repo, all products — 30+ minutes, often 45–60 min even on small repos (≈100 source files). Pro interfile analysis fans out across SAST + SCA + Secrets, so wall-clock cost is roughly additive. The skill will warn you before running this combination — pick it only when you genuinely need full coverage in one pass.
Not designed for keystroke-level feedback — run it deliberately before a commit or PR.
/fix-developer-portal-sec-findings
Pull your repo's open security findings from the developer portal, walk through them by type, propose fixes, and open a PR after you confirm. Three explicit pauses: before applying each fix, before pushing the branch, and before opening the PR.
What you need:
- Access to the developer portal.
- 1Password CLI (
op) installed and signed in (brew install 1password-cli, theneval $(op signin)). - An API token from the developer portal, saved in 1Password. To create it:
- Open the developer portal →
security→configtab. - Generate a new API token and copy the value.
- In 1Password (Employee vault by convention, but any vault you can read works — the skill auto-detects):
- Create a new item of type API Credentials.
- Name it
DP-SEC-FINDINGS-TOKEN. - Paste the token into the
credentialfield.
- Open the developer portal →
jqinstalled (brew install jq).- Push rights on the repo (for opening the PR).
- For pentest-type findings: the Atlassian connector enabled in Claude Code so the skill can fetch the full VULN ticket. If it isn't installed, the skill points you to Claude Code's connector marketplace.
Quick Start:
# Slug is auto-detected from `git remote get-url origin`:
/fix-developer-portal-sec-findings
# Or override the slug explicitly:
/fix-developer-portal-sec-findings <slug>
Example:
/fix-developer-portal-sec-findings
→ Detected repo from git remote: personio-android
→ Fetching open findings from developer portal…
Found 16 open findings for personio-android:
deps (Semgrep SCA) 16 findings (16 High)
→ Where would you like to start?
You: highest severity first
[High] deps: com.squareup.okhttp3:okhttp@4.9.3 → 4.12.0 (CVE-2023-3635)
Manifest: app/build.gradle.kts
Fix: Bump okhttp to 4.12.0 in app/build.gradle.kts, then `./gradlew dependencies`
→ Should I apply this fix on a new branch?
You: yes
✅ Branch fix/CVE-2023-3635-bump-okhttp created and committed.
→ Push the branch?
You: yes
✅ Pushed.
→ Open the PR?
You: yes
✅ PR opened: https://github.com/Personio-Internal/personio-android/pull/142
Why would you want this?
- Turn a long backlog of dashboard findings into a focused fix session.
- Get language-aware and finding-type-aware remediation guidance (different playbook per type: deps / secrets / pentest).
- One workflow from "what's open?" to "PR submitted" — without ever copying a token into chat or opening the dashboard.
Author
Product Security Team