PFCG role automation — turns the manual post-diagnosis grind (add a tcode, regenerate, user-compare, assign) into one-line commands where every write is confirm-gated with an explicit delta preview and PROVEN by an authoritative AGR_* RFC re-read (never "thinks" it changed a role). show is a read-only role dossier (AGR_DEFINE/AGR_TEXTS header, AGR_TCODES menu, AGR_USERS assignments, AGR_PROF generated profile + AGR_1251 auth-row count, T000 client modifiability). assign/unassign add/remove us...
Scanned 9/5/2026
Install to Claude Code
npx -y skills add sapdev-ai/sap-dev --skill sap-pfcg --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Sap Pfcg?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/sapdev-ai-sap-pfcg)More formats (shields.io, HTML) on the badges page.
---
name: sap-pfcg
description: |
PFCG role automation — turns the manual post-diagnosis grind (add a tcode, regenerate,
user-compare, assign) into one-line commands where every write is confirm-gated with an explicit
delta preview and PROVEN by an authoritative AGR_* RFC re-read (never "thinks" it changed a role).
show is a read-only role dossier (AGR_DEFINE/AGR_TEXTS header, AGR_TCODES menu, AGR_USERS
assignments, AGR_PROF generated profile + AGR_1251 auth-row count, T000 client modifiability).
assign/unassign add/remove users via the released BAPI_USER_ACTGROUPS_ASSIGN read-modify-write path
(pure RFC, full-set-replace from a fresh GET_DETAIL + the requested delta ONLY — never over-grants;
reuses /sap-su01's verified assignment writer, the binding ownership split: pfcg = role->users,
su01 = user->roles). create / add-tcodes / remove-tcodes / generate drive PFCG (SAPLPRGN_TREE) +
SUPC (SAPPROFC_NEW) via recorded GUI flows that NEVER enter the authorization tree (Phase 1's
make-or-break), behind a confirm gate + a Customizing TR (/sap-transport-request --type
customizing), each verified by an exact AGR_TCODES / AGR_PROF re-read. user-compare delegates
RHAUTUPD_NEW to /sap-run-report. The auth tree (auth-values/org-levels) is Phase 2; delete is out
of scope. v1 RFC legs are identical ECC6 + S/4; GUI legs are per-release with PFCG_NEEDS_RECORDING
degradation. Depends on /sap-suim (before/after grant diff) + the /sap-transport-request
Customizing-TR extension (both shipped). Prerequisites: pinned /sap-login RFC profile; a live GUI
session for create/menu/generate; NCo 3.1 (32-bit).
argument-hint: "show <ROLE> | add-tcodes <ROLE> <T1,T2> [--generate] | generate <ROLE> | assign <ROLE> <USER[,..]> | unassign <ROLE> <USER>"
---
# SAP PFCG Role Skill
You make the five safe Phase-1 role changes as one-liners: show (read-only dossier), add/remove
menu tcodes, generate the profile (via SUPC, never the auth tree), user-compare, and assign/unassign
users — every write confirm-gated on an explicit delta and verified by an authoritative RFC re-read.
Task: $ARGUMENTS
---
## Shared Resources
| File | Token / call | Purpose |
|---|---|---|
| `<SKILL_DIR>/references/sap_pfcg_verify.ps1` | `-Mode snapshot\|list` | Role dossier (show) + write-gate re-read |
| `<SKILL_DIR>/references/sap_pfcg_create.vbs` | GUI (`%%ROLE_NAME%%`·`%%ROLE_DESC%%`·`%%TRANSPORT%%`·`%%SESSION_PATH%%`·`%%ATTACH_LIB_VBS%%`·`%%SESSION_LOCK_VBS%%`) | PFCG create-single-role — **recorded on EC2 2026-07-11** (Role>Create>Role → desc → Save; step-verified, assembled-driver smoke-test pending) |
| `<SKILL_DIR>/references/sap_pfcg_generate.vbs` | GUI (`%%ROLE_NAME%%`·`%%SESSION_PATH%%`·`%%ATTACH_LIB_VBS%%`·`%%SESSION_LOCK_VBS%%`) | Profile generate — **recorded on EC2 2026-07-11**. Uses PFCG's **in-editor Generate** (auth-data screen 120 → Generate → confirm name; makes NO auth-tree edits) — supersedes the original SUPC plan per the "record GUI pfcg" instruction; `PFCG_NEEDS_RECORDING` (exit 3) if `btnPROFIL1` isn't locatable on a release |
| `<SKILL_DIR>/references/sap_pfcg_menu.vbs` | GUI | add/remove-tcodes menu flow — **`NEEDS_RECORDING`**: the menu-tab add-transaction goes through a GuiShell-toolbar `pressButton` whose fcode isn't drive-discoverable → needs SAP's built-in recorder (`/sap-gui-probe --record`, Mode R) |
| `/sap-su01` (assign/unassign) · `/sap-suim` (fetch-role diff) · `/sap-transport-request` (`--type customizing`) · `/sap-run-report` (RHAUTUPD_NEW) | sub-skills | Reused assignment writer / before-after diff / Customizing TR / user comparison |
| `<SAP_DEV_CORE_SHARED_DIR>/scripts/sap_rfc_lib.ps1` · `sap_attach_lib.vbs` (`%%ATTACH_LIB_VBS%%`) · `sap_session_lock.vbs` (`%%SESSION_LOCK_VBS%%`) | libs | RFC + Tier-3 attach + write lock |
| `<SAP_DEV_CORE_SHARED_DIR>/rules/safety_policy.md` + `<SAP_DEV_CORE_SHARED_DIR>/scripts/sap_safety_gate.ps1` | Rule 0 | Environment guard — Step 2 runs `-Action assert` first for every write mode |
---
## Step 0 — Directories + Logging
Resolve `work_dir` + `{RUN_TEMP}` (canonical one-liner — `sap_connection_lib.ps1` is dot-sourced
there — with `Write-Output ('RUN_TEMP=' + (Get-SapRunTemp))` appended). `{RUN_TEMP}` = the
per-run scratch dir holding the log state file; mint it once here and reuse (re-minting breaks
the `-Action end` state-file lookup). Start logging (`sap_log_helper.ps1`,
state `{RUN_TEMP}\sap_pfcg_run.json`). Pinned RFC profile; GUI session for create/menu/generate.
## Step 1 — Parse & Dispatch
`show` | `create` | `add-tcodes` | `remove-tcodes` | `generate` | `user-compare` | `assign` |
`unassign`. Uppercase ROLE/TCODES/USERS. Chained flags (`--generate --compare`) run under ONE
combined confirm gate.
## Step 2 — Preflight (write modes)
**Rule 0 first** (`safety_policy.md`; `show` skips it):
`powershell -NoProfile -ExecutionPolicy Bypass -File "<SAP_DEV_CORE_SHARED_DIR>\scripts\sap_safety_gate.ps1" -Action assert -Skill sap-pfcg` —
`SAFETY: ALLOW` (0) proceed; `TYPED_CONFIRM_REQUIRED` (3) -> the operator types the shown
`PROD <SID>/<CLIENT>` token, re-run with `-ConfirmationText '<their verbatim answer>'`, proceed only
on `ALLOW_CONFIRMED`; `REFUSED class=<C>` (1) / `ERROR` (2) -> **STOP**, end `FAILED` with
`-ErrorClass <C>`, relay the remediation lines — never bypass or drive PFCG manually instead. The
Step 4 confirm still applies after an ALLOW/ALLOW_CONFIRMED.
`sap_pfcg_verify.ps1 -Mode snapshot` gives client modifiability (T000) + role existence: refuse
`AUTH_CLIENT_NOT_MODIFIABLE`; create on an existing role -> `PFCG_ROLE_EXISTS`; the others on a
missing role -> `AUTH_ROLE_NOT_FOUND`. TSTC-validate each add-tcode; BAPI_USER_EXISTENCE_CHECK each
user.
## Step 3 — show / BEFORE snapshot
```bash
... sap_pfcg_verify.ps1 -Mode snapshot -Role <R> -OutDir "{RUN_TEMP}\pfcg"
```
`PFCG:` dossier lines (desc / menu_tcodes / assigned_users / generated_profile / auth_rows /
client modifiability) + `role_snapshot_<R>.tsv`. `show` renders this and ENDS. For write modes, also
capture the `/sap-suim fetch-role` grant-set TSV as the human-facing before-state.
## Step 4 — CONFIRM gate + write
**CONFIRM** (yes/no; typed role-name when T000 category=P): "I will <VERB> on role `<R>` in
`<SID>/<CLIENT>`: <exact delta>. Proceed?". On no -> `SKIPPED`. Then:
- **assign/unassign** -> delegate to `/sap-su01 assign|unassign <R> <USER>` (the reused
BAPI_USER_ACTGROUPS_ASSIGN full-set-replace path: fresh GET_DETAIL + the requested delta ONLY,
abort on RETURN E/A incl. CUA-child, verify AGR_USERS re-read).
- **create / generate (recorded GUI writes)** -> for create, resolve a **Customizing TR** via
`/sap-transport-request --type customizing` (single roles are usually client-local, so the driver
tolerates no TR popup; generate needs no TR). Substitute the attach + lock + arg tokens, **bake**
the resolved session path, and run the driver via **32-bit cscript**:
```powershell
$shared = '<SAP_DEV_CORE_SHARED_DIR>\scripts'
. "$shared\sap_connection_lib.ps1"
# BAKE the path into %%SESSION_PATH%% (attach Strategy 1) rather than exporting
# $env:SAPDEV_SESSION_PATH here: this generator is a SEPARATE process from the one
# that runs cscript, so the env var would already be gone and the attach lib would
# silently fall through to its sole-connection default (2026-08-06).
$sessionPath = Get-SapCurrentSessionPath -WorkTemp '{WORK_TEMP}' # or the --session value
$drv = 'sap_pfcg_create.vbs' # or 'sap_pfcg_generate.vbs'
$vbs = [IO.File]::ReadAllText("<SKILL_DIR>\references\$drv", [Text.Encoding]::UTF8)
$vbs = $vbs.Replace('%%ATTACH_LIB_VBS%%', "$shared\sap_attach_lib.vbs")
$vbs = $vbs.Replace('%%SESSION_LOCK_VBS%%', "$shared\sap_session_lock.vbs")
$vbs = $vbs.Replace('%%SESSION_PATH%%', $sessionPath)
$vbs = $vbs.Replace('%%ROLE_NAME%%', '<ROLE>')
$vbs = $vbs.Replace('%%ROLE_DESC%%', '<short description>') # create only
$vbs = $vbs.Replace('%%TRANSPORT%%', '<customizing-TR>') # create only; empty -> ABORT if PFCG prompts
[IO.File]::WriteAllText('{RUN_TEMP}\pfcg_run.vbs', $vbs, [System.Text.UnicodeEncoding]::new($false, $true))
```
Declare the GUI target in the SAME block as cscript — the attach lib reads
`SAPDEV_EXPECT_SYSTEM`/`_CLIENT` from the process environment, so a role create /
generate can never land on a system other than the one the RFC leg resolved:
```powershell
. '<SAP_DEV_CORE_SHARED_DIR>\scripts\sap_connection_lib.ps1'
Set-SapGuiTargetExpectation -WorkTemp '{WORK_TEMP}' | Out-Null
& 'C:\Windows\SysWOW64\cscript.exe' //NoLogo "{RUN_TEMP}\pfcg_run.vbs"
```
Parse `SUCCESS:` / `ERROR:` plus the machine markers — `PFCG_NO_AUTH_CREATE:` (create; missing
S_USER_AGR activity 01 — verified on S4D/MICHAELLI + S4G/KM717; EC2/DEV102 has it), `ABORT_EMPTY_TR:`
(create; a TR popup appeared with no `%%TRANSPORT%%`), `PFCG_NEEDS_RECORDING:` **exit 3** (generate;
`btnPROFIL1` not locatable on this release → recapture). **generate uses PFCG's in-editor Generate**
— it enters the auth-data screen (120) but makes NO auth-value/org-level edits (only Generate +
confirm the proposed profile name + save); this supersedes the original SUPC design per the
"record GUI pfcg" decision.
- **add-tcodes / remove-tcodes** -> `sap_pfcg_menu.vbs` ships **`NEEDS_RECORDING`**: the menu-tab
add-transaction drives a GuiShell-toolbar button (`cntlTOOL_CONTROL`) whose `pressButton` function
code is not discoverable by dumping the property tree, so drive-mode cannot capture it. Emit
`PFCG_NEEDS_RECORDING` and point to `/sap-gui-probe --record` (SAP's built-in recorder, Mode R) —
a clean abort until the flow is captured with a human operator's click as ground truth.
- **user-compare** -> `/sap-run-report RHAUTUPD_NEW` role-scoped (or PFCG_TIME_DEPENDENCY for
`--all-roles`).
## Step 5 — AFTER verify (authoritative)
Mode-specific RFC re-read via `sap_pfcg_verify.ps1`: AGR_TCODES before/after diff == the requested
delta EXACTLY (else `PFCG_VERIFY_MISMATCH`, FAILED, show actual — even if the status bar said S);
generate -> AGR_PROF + auth_rows present (0 -> `PFCG_GENERATE_FAILED`; org-level warnings ->
`GENERATED_WITH_WARNINGS`, stated not hidden); assign -> AGR_USERS set == previous ± delta. Render
the `/sap-suim` before/after diff.
## Step 6 — Register
`Register-SapArtifact` (kinds `auth-role-snapshot` / `auth-role-change` / `auth-assignment`; scope
`ROLE_<NAME>`; verdict) for `/sap-evidence-pack`.
## Final — Log End
Log end. Error classes: `AUTH_CLIENT_NOT_MODIFIABLE`, `PFCG_ROLE_EXISTS`, `PFCG_VERIFY_MISMATCH`,
`PFCG_GENERATE_FAILED`, `PFCG_NEEDS_RECORDING`; reused `RFC_LOGON_FAILED` / `GUI_TIMEOUT` /
`TR_NOT_MODIFIABLE` / `AUTH_ROLE_NOT_FOUND` / `AUTH_USER_NOT_FOUND` / `AUTH_TCODE_NOT_FOUND`.
---
## Scope & Limitations (v1)
- **show live-verified on S4D (S/4HANA 1909) 2026-07-11:** `show SAP_BC_BASIS_ADMIN` returned the
full dossier — desc "System Administrator", 38 menu tcodes, 0 assigned users, generated profile
T-SD020189, 146 auth rows, client category=T / modifiable=YES; a nonexistent role ->
`AUTH_ROLE_NOT_FOUND`. EC2 (ECC 6) was probed in-plan (all AGR_* + BAPI_USER_ACTGROUPS_ASSIGN
FMODE=R + PFCG/SUPC programs identical) but unreachable at build time; the RFC legs are one code
path. **Build finding:** AGR_TIMESTMP does not exist -> generation is verified via AGR_PROF +
AGR_1251 auth-row count, not a timestamp.
- **assign/unassign is pure RFC** (BAPI_USER_ACTGROUPS_ASSIGN, FMODE=R both releases) and REUSES
/sap-su01's verified writer (the binding ownership split — one implementation, two views). It
full-set-replaces from a fresh GET_DETAIL + the requested delta ONLY (never over-grants) and aborts
on any RETURN E/A.
- **create/add-tcodes/remove-tcodes/generate are confirm-gated GUI writes**, each verified by an EXACT
AGR_* re-read (a status-'S' with the wrong delta is still a mismatch failure) and (create) a
Customizing TR via the shipped `/sap-transport-request --type customizing` extension.
**Recorded 2026-07-11 (EC2 ERP/800, ECC6 rel 731; S/4 structurally identical — same SAPLPRGN_TREE
control IDs, only the on-screen text differs):** `create` (Role>Create>Role → description → Save;
single roles are client-local so no TR popup fired) and `generate` (Authorizations tab → in-editor
Generate → confirm the proposed profile name → save). **Build finding:** role creation needs
S_USER_AGR activity 01 — S4D/MICHAELLI and S4G/KM717 both LACK it (`PFCG_NO_AUTH_CREATE`), only
EC2/DEV102 has it, so the create/generate legs were recorded there. **Design shift:** `generate` now
uses PFCG's **in-editor** Generate (it enters the auth-data screen but makes NO auth-value/org-level
edits — only Generate + confirm the name + save), superseding the plan's SUPC list flow per the
"record GUI pfcg" instruction. **`add-tcodes`/`remove-tcodes` stays `NEEDS_RECORDING`** — the
menu-tab add-transaction drives a GuiShell-toolbar button whose `pressButton` fcode is not
drive-discoverable, so it needs SAP's built-in recorder (`/sap-gui-probe --record`, Mode R).
- **The auth tree is Phase 2.** v1 does NOT patch S_TABU_DIS values / org levels — it answers with
the /sap-auth-diagnose proposal file + a manual PFCG pointer (never improvises tree edits). Role
delete is out of scope. Composite-role writes (AGR_AGRS) are v1.5.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!