Skip to content

D-IAM-1 preset roles from the directory; D-IAM-3 per-property authorization contract - #42

Merged
AdaWorldAPI merged 3 commits into
mainfrom
ccr-1d749cc5-q8s5qs
Oct 21, 2026
Merged

AdaWorldAPI merged 3 commits into
mainfrom
ccr-1d749cc5-q8s5qs

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented Oct 21, 2026 •

Copy link
Copy Markdown
Owner

D-IAM-1: preset roles

  • hubspo_port::RBAC_ROLES names six roles: crm_super_admin, crm_admin, crm_sales_user, crm_service_user, crm_marketing_user and crm_view_only. hubspo-port keeps only the plug declaration.
  • hubspo_iam::roles::Catalogue is the OGAR GrantSource: one grant per plugged concept (22) per role. roles::bind() binds RBAC_PLUG against OGAR without errors.
  • Roles come from the directory. roles::request_actors reuses dir-sim's ViewActors:
    • roles are granted to security groups in OGAR's group-role policy (GroupRoles::from_policy);
    • they are inherited through SID chains only, and the binding filters them;
    • they are read once per request;
    • a group whose grants were never read refuses the request.
  • The verb table is provisional (ISS-PRESET-VERBS-PROVISIONAL). Tenant permission sets are open (ISS-PERMISSION-SETS-NOT-ROLES).

D-IAM-3 contract (ISS-PACKED-RUN-RBAC-GRAIN, option b)

hubspo_iam::fields decides a read with two masks, and both must allow it:

  • outer: the role's WideFieldMask. It checks the property's lane, or position 0, which covers only the packed container;
  • inner: PropertyGrants, a set of stable property ordinals per role and concept. It never names a lane, so re-slotting a property changes no decision.

Why not reuse the existing masks: WideFieldMask cannot represent the inner set. Its positions are u8, which cannot name contact's 272 ordinals, and it carries no schema version. So the inner set is a local type, and no upstream abstraction is added.

How it is used:

  • Projection::compile runs once per request and concept. It records a Stamp: concept, schema version, the PropertyGrants generation and the outer PolicyVersion.
  • Every read presents the current stamp:
    • project drops hidden and unknown properties;
    • require refuses filters, sorts and aggregates over them;
    • any stamp difference refuses everything: another concept, another schema version, or a revoked grant (Codex review).

Not yet done: wiring into output paths, which do not exist yet, and default grants per role.

Tests

  • hubspo-iam: 24 unit tests (12 roles + 12 fields) and 3 directory integration tests.
  • Negative tests: a grant on school exposes none of date_of_birth, gender, marital_status or military_status, in output or in predicates.
  • A deal projection is refused on a contact row, and a revoked grant invalidates the projection.
  • 14 disable runs, each red:
    • roles (5): view-only given edit, sales given delete, admin given user delete, an unknown role defined, service losing tickets;
    • fields (8): inner grant ignored, outer mask ignored, stale schema version accepted, require passing hidden properties, cross-role mask combination, concept not stamped, admits ignoring the concept, revoke not bumping the generation;
    • directory (1): an unread group accepted.
  • cargo fmt --check, cargo clippy -D warnings and cargo test --workspace are green.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PPcakjk7ioQsnasmNDtc5z

hubspo-port declares the six preset role names in RBAC_ROLES; the grants
move to hubspo-iam::roles::Catalogue (one const grant per plugged concept
per role, from a provisional verb table) and hubspo-iam::roles::bind binds
the plug green. Field masks stay the default (D-IAM-3); actors come from
the request's identity. Tenant permission sets and the verb table are open
(ISS-PERMISSION-SETS-NOT-ROLES, ISS-PRESET-VERBS-PROVISIONAL).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPcakjk7ioQsnasmNDtc5z
…contract

hubspo_iam::roles::request_actors resolves a request's roles once from the
directory through dir-sim's ViewActors (security-group grants from OGAR's
group-role policy), refusing on an unread group.

hubspo_iam::fields is the D-IAM-3 contract for ISS-PACKED-RUN-RBAC-GRAIN
option (b): a read needs the outer WideFieldMask (lane, or position 0 for
the packed run) and an inner grant by stable property ordinal. Projections
compile once per request against one schema version; project drops hidden
and unknown values, require refuses predicates over them, and a stale
version refuses everything. Negative tests: school does not grant
date_of_birth, gender, marital_status or military_status.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPcakjk7ioQsnasmNDtc5z
@AdaWorldAPI
AdaWorldAPI marked this pull request as ready for review October 21, 2026 00:47
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-21T00:49:59.318076Z e20ba13 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e20ba1300d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/hubspo-iam/src/fields.rs
Comment thread crates/hubspo-iam/src/fields.rs Outdated
…ons)

Codex on #42: a projection checked only the schema version, so a deal
projection could read a contact row at the same version (deal ordinal 8
over contact ordinal 8, date_of_birth), and a revoked grant kept
authorizing. Projections now record a Stamp (concept, schema version,
PropertyGrants generation, outer PolicyVersion); project, require and
admits take the current stamp and refuse any difference. PropertyGrants
gains revoke and a generation bumped by every change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPcakjk7ioQsnasmNDtc5z
@AdaWorldAPI
AdaWorldAPI merged commit 28ba8ce into main Oct 21, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants