AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Nacl Sa Roles

skill-itsalt-nacl-nacl-sa-roles · by ITSalt

|

No reviews yet
0 installs
43 views
0.0% view→install

Install

$ agentstack add skill-itsalt-nacl-nacl-sa-roles

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-itsalt-nacl-nacl-sa-roles)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Nacl Sa Roles? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

/nacl-sa-roles --- System Roles & Permissions (Graph)

Purpose

Define system roles, build the CRUD permission matrix against DomainEntities, and create BA-to-SA role mapping edges. All data lives in Neo4j -- no markdown artifacts.

Shared references: nacl-core/SKILL.md


Neo4j Tools

| Tool | Usage | |------|-------| | mcp__neo4j__read-cypher | Read-only queries (fetch BA roles, existing SystemRoles, DomainEntities) | | mcp__neo4j__write-cypher | Create/update/delete nodes and edges | | mcp__neo4j__get-schema | Introspect current graph schema |


Modes

Mode IMPORT_BA

Import BA business roles from Neo4j graph as SystemRole candidates with N:M mapping and full handoff traceability.

When: BA layer populated in Neo4j (BusinessRole nodes exist), SA role model not yet created.

Mode CREATE

Create a single new SystemRole interactively with permissions.

When: User asks to add a new system role not sourced from BA (e.g. Admin, System).

Parameter: role_name -- name of the role to create.

Mode MODIFY

Modify an existing SystemRole: change permissions, add/remove MAPPED_TO edges, update properties.

When: User asks to change permissions or properties of an existing role.

Parameter: role_name -- name of the role to modify.

Mode FULL

Build the complete role model: all roles, permission matrix, data scope rules.

When: After nacl-sa-architect and nacl-sa-domain, when building the full role model from scratch.


Workflow

+-----------------+    +-----------------+    +-----------------+    +-----------------+
| Phase 1         |    | Phase 2         |    | Phase 3         |    | Phase 4         |
| Identify        |--->| CRUD            |--->| Data scope      |--->| Workflow        |
| roles           |    | permission      |    | constraints     |    | permissions     |
|                 |    | matrix          |    |                 |    |                 |
+-----------------+    +-----------------+    +-----------------+    +-----------------+

Each phase ends with:

  1. Summary -- what was understood
  2. Confirmation -- user approval
  3. Graph writes -- create/update nodes and edges in Neo4j

Do not proceed to the next phase without explicit user confirmation!


Pre-check

  1. Verify DomainEntity nodes exist (needed for permission matrix):
// mcp__neo4j__read-cypher
MATCH (de:DomainEntity)
OPTIONAL MATCH (m:Module)-[:CONTAINS_ENTITY]->(de)
RETURN de.id AS id, de.name AS name, m.name AS module
ORDER BY m.name, de.name

If no DomainEntities found -- suggest running nacl-sa-domain first.

  1. Check existing SystemRole nodes:
// mcp__neo4j__read-cypher
MATCH (sr:SystemRole)
OPTIONAL MATCH (br:BusinessRole)-[:MAPPED_TO]->(sr)
OPTIONAL MATCH (sr)-[p:HAS_PERMISSION]->(de:DomainEntity)
RETURN sr.id AS id, sr.name AS name, sr.type AS type, sr.description AS description,
       collect(DISTINCT br.full_name) AS mapped_from_ba,
       count(DISTINCT p) AS permission_count
ORDER BY sr.id

If SystemRoles already exist -- warn about possible overwrite and suggest MODIFY mode.

  1. Check for available BA roles (for IMPORT_BA suggestion):
// mcp__neo4j__read-cypher
MATCH (br:BusinessRole)
WHERE NOT (br)-[:MAPPED_TO]->(:SystemRole)
RETURN count(br) AS unmapped_ba_roles

If unmapped BA roles exist -- suggest starting with IMPORT_BA mode.


Mode: IMPORT_BA

Step 1: Read BA roles from graph

Goal: Fetch all BusinessRole nodes and their process associations.

Cypher -- fetch all BA roles with context:

// mcp__neo4j__read-cypher
MATCH (br:BusinessRole)
OPTIONAL MATCH (br)-[:OWNS]->(owned:BusinessProcess)
OPTIONAL MATCH (br)-[:PARTICIPATES_IN]->(part:BusinessProcess)
OPTIONAL MATCH (br)-[:PERFORMED_BY]-(ws:WorkflowStep)
RETURN br.id AS id, br.full_name AS name, br.description AS description,
       collect(DISTINCT owned.name) AS owns_processes,
       collect(DISTINCT part.name) AS participates_in,
       collect(DISTINCT ws.function_name) AS performs_steps
ORDER BY br.id

Cypher -- check already-mapped BA roles:

// mcp__neo4j__read-cypher
MATCH (br:BusinessRole)-[:MAPPED_TO]->(sr:SystemRole)
RETURN br.id AS ba_id, br.full_name AS ba_name,
       sr.id AS sa_id, sr.name AS sa_name

If all BA roles already mapped -- tell the user. Suggest CREATE or MODIFY mode.

Cypher -- fetch DomainEntities for permission context:

// mcp__neo4j__read-cypher
MATCH (de:DomainEntity)
OPTIONAL MATCH (m:Module)-[:CONTAINS_ENTITY]->(de)
RETURN de.id AS id, de.name AS name, m.name AS module
ORDER BY m.name, de.name

Cypher -- fetch UseCases for actor assignment context:

// mcp__neo4j__read-cypher
MATCH (uc:UseCase)
OPTIONAL MATCH (m:Module)-[:CONTAINS_UC]->(uc)
RETURN uc.id AS id, uc.name AS name, m.name AS module
ORDER BY m.name, uc.id

Step 2: Propose N:M mapping BA -> SA

Goal: For each BusinessRole, propose one or more SystemRoles. Multiple BA roles may merge into one SA role. One BA role may split into multiple SA roles.

Mapping rules:

| Situation | Action | Example | |-----------|--------|---------| | 1 BA role = 1 SA role | Direct mapping (1:1) | "Менеджер" -> "Manager" | | 1 BA role -> N SA roles | Split by access level (1:N) | "Руководитель" -> "TeamLead", "DepartmentHead" | | N BA roles -> 1 SA role | Merge similar system rights (N:1) | "Кладовщик", "Приёмщик" -> "WarehouseOperator" | | No BA source | System-only role (new) | -- -> "Admin", "System" |

Always consider adding these system-only roles if not present in BA:

  • Admin -- full system access, user management, configuration
  • System -- automated/background processes (if the system has scheduled tasks, integrations, etc.)

Present to user:

**BA -> SA Role Mapping**

Found {N} BA business roles -> proposing {M} SA system roles:

| # | BA Role(s) | SA Role (candidate) | Type | Mapping |
|---|-----------|--------------------|----|---------|
| 1 | {BA Role 1} | {SA Role 1} | internal | 1:1 |
| 2 | {BA Role 2}, {BA Role 3} | {SA Role 2} | internal | N:1 (merge) |
| 3 | {BA Role 4} | {SA Role 3a}, {SA Role 3b} | external | 1:N (split) |
| 4 | -- | Admin | internal | New SA role |
| 5 | -- | System | internal | New SA role |

Questions:
1. Is the proposed BA -> SA mapping correct?
2. Should any roles be split or merged differently?
3. Which additional system-only roles are needed?
4. Role types: internal (employee) or external (client, partner)?

Step 3: Create SystemRole nodes and MAPPED_TO edges

Goal: Write SystemRole nodes and BA->SA handoff edges to Neo4j.

Cypher -- get next SystemRole ID:

// mcp__neo4j__read-cypher
MATCH (sr:SystemRole)
WITH max(toInteger(replace(sr.id, 'SR-', ''))) AS maxNum
RETURN 'SR-' + apoc.text.lpad(toString(coalesce(maxNum, 0) + 1), 2, '0') AS nextId

If apoc is not available, compute the next ID in the agent and pass it as a parameter.

Cypher -- create SystemRole:

// mcp__neo4j__write-cypher
MERGE (sr:SystemRole {id: $id})
SET sr.name = $name,
    sr.type = $type,
    sr.description = $description,
    sr.responsibilities = $responsibilities,
    sr.system_only = $systemOnly,
    sr.status = 'draft',
    sr.created = datetime()

Parameters:

  • $id -- format SR-NN (e.g. "SR-01")
  • $name -- English PascalCase (e.g. "OrderManager")
  • $type -- "internal" or "external"
  • $description -- Russian description of the role
  • $responsibilities -- semicolon-separated list of main responsibilities (Russian)
  • $systemOnly -- boolean. true for infrastructure-only roles that never appear in BA mapping (e.g., System, Worker, Cron); false for end-user-facing roles (Teacher, Student, OrderManager, etc.). Used by validator XL8.2 to skip BA-mapping requirements on infrastructure roles. If forgotten, nacl-sa-flags backfill-all defaults it to false and the user can flip it later via /nacl-sa-flags set-system-only --role true.

Cypher -- create MAPPED_TO handoff edge (BusinessRole -> SystemRole):

// mcp__neo4j__write-cypher
MATCH (br:BusinessRole {id: $baRoleId}), (sr:SystemRole {id: $saRoleId})
MERGE (br)-[:MAPPED_TO]->(sr)

Execute for each BA-to-SA pair in the confirmed mapping table.

After all roles created, verify:

// mcp__neo4j__read-cypher
MATCH (sr:SystemRole)
OPTIONAL MATCH (br:BusinessRole)-[:MAPPED_TO]->(sr)
RETURN sr.id AS id, sr.name AS name, sr.type AS type,
       collect(DISTINCT {ba_id: br.id, ba_name: br.full_name}) AS mapped_from
ORDER BY sr.id

Present summary:

**Step 3 complete: SystemRole nodes created**

| SA Role | ID | Type | Mapped from BA |
|---------|-----|------|---------------|
| {name} | {id} | {type} | {ba_names or "New SA role"} |

Total: {N} SystemRole nodes, {M} MAPPED_TO edges

After confirmation -> proceed to Phase 2 (CRUD matrix).


Phase 1: Identify Roles (FULL / CREATE modes)

Goal: Determine all system roles.

Mode FULL

If BA roles exist in the graph, start with IMPORT_BA Steps 1-3 to pre-populate. Then continue here to review and add system-only roles.

If no BA roles -- gather roles from user.

Cypher -- load context for role proposal:

// mcp__neo4j__read-cypher
MATCH (m:Module)
OPTIONAL MATCH (m)-[:CONTAINS_UC]->(uc:UseCase)
OPTIONAL MATCH (m)-[:CONTAINS_ENTITY]->(de:DomainEntity)
RETURN m.name AS module,
       collect(DISTINCT uc.name) AS use_cases,
       collect(DISTINCT de.name) AS entities
ORDER BY m.name

Present to user:

Based on the system architecture and domain model I propose the following roles:

1. **{Role 1}** ({type: internal/external}) -- {description, what the role does}
2. **{Role 2}** ({type}) -- {description}
3. **Admin** (internal) -- full system access, configuration, user management

Questions:
1. Are the proposed roles correct?
2. Any additional roles?
3. Can one user hold multiple roles?
4. Is there a role hierarchy (permission inheritance)?

Mode CREATE

Ask user for role details:

**New SystemRole: {name}**

1. English name (PascalCase): {suggestion}
2. Type: internal / external?
3. Description: ?
4. Main responsibilities (3-5 items): ?
5. Map to existing BA role? (optional)

Confirm?

Create the SystemRole node using the Cypher from IMPORT_BA Step 3.

Rules

  • Minimum 2 roles (otherwise no role model needed)
  • Maximum 7 roles (otherwise reconsider decomposition)
  • Each role must differ from others by at least one module or access level
  • Guest / unauthenticated user -- separate role if public access exists
  • Admin -- always present if the system requires configuration

Phase 2: CRUD Permission Matrix

Goal: Define access for each role to each DomainEntity (Create, Read, Update, Delete).

Step 2.1: Fetch all DomainEntities

// mcp__neo4j__read-cypher
MATCH (de:DomainEntity)
OPTIONAL MATCH (m:Module)-[:CONTAINS_ENTITY]->(de)
RETURN de.id AS id, de.name AS name, m.name AS module
ORDER BY m.name, de.name

Step 2.2: Fetch all SystemRoles

// mcp__neo4j__read-cypher
MATCH (sr:SystemRole)
RETURN sr.id AS id, sr.name AS name, sr.type AS type
ORDER BY sr.id

Step 2.3: Propose CRUD matrix

Build a table: rows = DomainEntities, columns = SystemRoles. For each cell determine: C/R/U/D or combination.

Use BA context to inform proposals:

  • If a BA role OWNS a process that PRODUCES an entity -> C (create)
  • If a BA role PARTICIPATES_IN a process that READS an entity -> R (read)
  • If a BA role performs steps that MODIFY an entity -> U (update)
  • Admin gets CRUD on everything

Cypher -- BA role-entity interaction (for informed proposals):

// mcp__neo4j__read-cypher
MATCH (br:BusinessRole)-[:PERFORMED_BY]-(ws:WorkflowStep)
MATCH (ws)-[rel:READS|PRODUCES|MODIFIES]->(be:BusinessEntity)
MATCH (be)-[:REALIZED_AS]->(de:DomainEntity)
OPTIONAL MATCH (br)-[:MAPPED_TO]->(sr:SystemRole)
RETURN sr.name AS system_role,
       de.name AS domain_entity,
       collect(DISTINCT type(rel)) AS interactions
ORDER BY sr.name, de.name

Present to user:

**CRUD Permission Matrix**

| DomainEntity | {Role 1} | {Role 2} | {Role 3} | Admin |
|-------------|----------|----------|----------|-------|
| {Entity 1}  | CR       | R        | --       | CRUD  |
| {Entity 2}  | CRUD     | R        | R(own)   | CRUD  |
| {Entity 3}  | --       | CRU      | R        | CRUD  |

Legend:
- C = Create, R = Read, U = Update, D = Delete
- R(own) = read only own records
- CRU(own) = create, read, update only own records
- -- = no access

Questions:
1. Are the access levels correct?
2. Any entities that should be restricted further?
3. Should we distinguish "list view" vs "detail view"?

Step 2.4: Write HAS_PERMISSION edges to Neo4j

Cypher -- create HAS_PERMISSION edge:

// mcp__neo4j__write-cypher
MATCH (sr:SystemRole {id: $roleId}), (de:DomainEntity {id: $entityId})
MERGE (sr)-[p:HAS_PERMISSION]->(de)
SET p.crud = $crud,
    p.scope = $scope

Parameters:

  • $roleId -- SystemRole.id (e.g. "SR-01")
  • $entityId -- DomainEntity.id (e.g. "DE-Order")
  • $crud -- combination of C/R/U/D letters (e.g. "CRUD", "CR", "R")
  • $scope -- data visibility scope: "all", "own", "department", "assigned" (default "all")

Execute for each confirmed (role, entity) pair from the matrix.

CRUD notation rules:

  • "CRUD" -- full access
  • "CR" -- create and read
  • "R" -- read only
  • "RU" -- read and update
  • "" (empty string) or no edge -- no access (do not create HAS_PERMISSION edge for no-access pairs)

Step 2.5: Verify permission matrix

// mcp__neo4j__read-cypher
MATCH (sr:SystemRole)-[p:HAS_PERMISSION]->(de:DomainEntity)
RETURN sr.name AS role, de.name AS entity, p.crud AS crud, p.scope AS scope
ORDER BY sr.name, de.name

Present summary:

**Phase 2 complete: CRUD matrix written to graph**

| DomainEntity | {Role 1} | {Role 2} | ... | Admin |
|-------------|----------|----------|-----|-------|
| {Entity}    | {crud}   | {crud}   | ... | CRUD  |

Total: {N} HAS_PERMISSION edges

Phase 3: Data Scope Constraints

Goal: Define which records each role can see (row-level security).

Questions

For each role, let's define data visibility:

1. **{Role 1}**: Sees {all data / only own / only department}?
2. **{Role 2}**: Sees {all data / only own}?

Questions:
1. Should data be filtered by ownership?
2. Is there an organizational hierarchy (departments, branches)?
3. Should a manager see other managers' data?

Scope Values

| Scope | Description | Filter Rule | |-------|-------------|-------------| | all | Sees all records | No filter | | own | Only records where user = creator/owner | entity.owner_id = current_user.id | | department | Records from user's department | entity.department_id = current_user.department_id | | assigned | Records explicitly assigned to user | entity.assignee_id = current_user.id |

Update HAS_PERMISSION scope

For each (role, entity) pair that needs scope restriction:

// mcp__neo4j__write-cypher
MATCH (sr:SystemRole {id: $roleId})-[p:HAS_PERMISSION]->(de:DomainEntity {id: $entityId})
SET p.scope = $scope,
    p.scope_rule = $scopeRule

Parameters:

  • $scope -- "all", "own", "department", "assigned"
  • $scopeRule -- human-readable filter rule (e.g. "order.clientid = currentuser.id")

Verify data scope

// mcp__neo4j__read-cypher
MATCH (sr:SystemRole)-[p:HAS_PERMISSION]->(de:DomainEntity)
WHERE p.scope <> 'all'
RETURN sr.name AS role, de.name AS entity, p.crud AS crud,
       p.scope AS scope, p.scope_rule AS scope_rule
ORDER BY sr.name, de.name

Present summary:

**Phase 3 complete: Data scope constraints**

| Role | Entity | CRUD | Scope | Rule |
|------|--------|------|-------|------|
| {role} | {entity} | {crud} | {scope}

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [ITSalt](https://github.com/ITSalt)
- **Source:** [ITSalt/NaCl](https://github.com/ITSalt/NaCl)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.