shopify-admin-staff-account-audit
SkillSecurityRead-only: reviews staff accounts for stale logins, inactive status, and overpermissioned roles to surface security and access hygiene issues.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the shopify-admin-staff-account-audit skill
What this skill tells your AI
The instructions your AI receives, as published by 40rty-ai/shopify-admin-skills in skills/store-management/shopify-admin-staff-account-audit/SKILL.md and read by ahel’s review.
Purpose
Audits all staff member accounts on the store to surface security and access-hygiene risks. Flags accounts that have not logged in for more than stale_days days, accounts that are inactive but still provisioned, and accounts with full / shop-owner-equivalent permissions. Read-only — no mutations. Provides the data foundation for a follow-up access review or deprovisioning workflow.
Prerequisites
- Authenticated Shopify CLI session:
shopify store auth --store <domain> --scopes read_users - API scopes:
read_users - Caller must be Shop Owner or have staff-management permissions to query staff data
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| store | string | yes | — | Store domain (e.g., mystore.myshopify.com) |
| stale_days | integer | no | 90 | Flag accounts with no login activity in this many days |
| include_inactive | bool | no | true | Include accounts where active: false in the audit output |
| include_owner | bool | no | false | Include the shop owner row in flagged-account counts |
| format | string | no | human | Output format: human or json |
Safety
ℹ️ Read-only skill — no mutations are executed. Safe to run at any time. No staff accounts are deactivated or modified by this skill.
Workflow Steps
-
OPERATION:
staffMembers— query Inputs:first: 250, selectid,name,email,active,isShopOwner,accountType,locale,lastSeen, pagination cursor Expected output: All staff members with status and last-login data; paginate untilhasNextPage: false -
Compute
days_since_last_seenper member. Flag any member withdays_since_last_seen > stale_daysas stale. -
Flag any member with
active: false(oraccountType: SUSPENDED) as inactive but provisioned. -
Flag any member with
isShopOwner: trueoraccountType: COLLABORATORwith full permissions as high privilege for review. -
Cross-tabulate: produce per-account record with all flags joined (
stale,inactive,high_privilege).
GraphQL Operations
# staffMembers:query — validated against api_version 2025-01
query StaffAccountAudit($after: String) {
staffMembers(first: 250, after: $after) {
edges {
node {
id
name
email
active
isShopOwner
accountType
locale
exists
phone
avatar {
url
}
privateData {
accountSettingsUrl
createdAt
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
Session Tracking
Claude MUST emit the following output at each stage. This is mandatory.
On start, emit:
╔══════════════════════════════════════════════╗
║ SKILL: Staff Account Audit ║
║ Store: <store domain> ║
║ Started: <YYYY-MM-DD HH:MM UTC> ║
╚══════════════════════════════════════════════╝
After each step, emit:
[N/TOTAL] <QUERY|MUTATION> <OperationName>
→ Params: <brief summary of key inputs>
→ Result: <count or outcome>
On completion, emit:
For format: human (default):
══════════════════════════════════════════════
STAFF ACCOUNT AUDIT (stale threshold: <stale_days> days)
Total staff accounts: <n>
Active: <n>
Inactive (provisioned): <n>
Stale logins (>Nd): <n> (<pct>%)
High-privilege roles: <n>
Flagged accounts (top by risk):
"<name>" <email> last_seen: <Nd ago> flags: <stale,high_priv>
Output: staff_audit_<date>.csv
══════════════════════════════════════════════
For format: json, emit:
{
"skill": "staff-account-audit",
"store": "<domain>",
"stale_days_threshold": 90,
"total_accounts": 0,
"active_accounts": 0,
"inactive_accounts": 0,
"stale_accounts": 0,
"high_privilege_accounts": 0,
"output_file": "staff_audit_<date>.csv"
}
Output Format
CSV file staff_audit_<YYYY-MM-DD>.csv with columns:
staff_id, name, email, account_type, is_shop_owner, active, last_seen, days_since_last_seen, is_stale, is_inactive, is_high_privilege, flags
Error Handling
| Error | Cause | Recovery |
|---|---|---|
THROTTLED | API rate limit exceeded | Wait 2 seconds, retry up to 3 times |
ACCESS_DENIED on staffMembers | Caller lacks read_users or staff-mgmt permission | Re-auth as Shop Owner / staff-admin |
lastSeen: null on a staff member | Account never logged in | Treat as days_since_last_seen = days_since_account_created; flag as stale |
| Empty staff list | Single-operator store (owner only) | Exit with 1 row (the owner); skill is still useful for record-keeping |
Best Practices
- Run quarterly (90-day cadence) as part of routine access reviews. Pair with the offboarding checklist — every former employee should be revoked, not merely deactivated.
- Use
stale_days: 30for high-risk stores (high-volume, large staff) andstale_days: 180for very small teams where seasonal access is normal. - Sort the CSV by
days_since_last_seendescending to prioritize the longest-stale accounts first. - High-privilege accounts (Shop Owner, full-permission collaborators) should have unique strong credentials and 2FA — treat any stale high-privilege account as a P0 review item.
- Export the CSV into your access-review tracker; do not deactivate accounts blindly — confirm with the account holder's manager first.
- Cross-reference flagged stale accounts with recent
staffMember-scoped audit log events before deprovisioning to ensure there is no in-flight work.
Signals
- GitHub stars
- 187
- Forks
- 18
- Last commit
- Aug 2026
ahel review
S4info
community integration — published by 40rty-ai, not shopify
Automated review, not a security audit. Ruleset v1.
Advanced
- Catalog kind
- skill
- Gateway key
shopify-admin-staff-account-audit- Source
- github.com/40rty-ai/shopify-admin-skills