配置权限
本页尚未翻译,以下显示英文原文。

Positions

Model job functions and audience anchors with positions.

Positions describe the job function a user holds — "Sales Manager", "Support Agent", "Auditor". Since ObjectStack 13 (Permission Model v2, ADR-0090), positions are the single people-grouping concept: the legacy Role and Profile frameworks were consolidated into positions and removed from the protocol.

Positions are intentionally flat. There is no parent field and no position hierarchy — reporting structure and subtree-based visibility live on the business-unit tree instead.

Position responsibilities

Use positions to model:

  • job functions ("Sales Manager", "Recruiter", "Auditor");
  • audience targeting for apps, tabs, and books;
  • approval responsibility (approvers of type position expand to the current holders automatically);
  • distribution of permission sets to everyone holding the same function.

Use business units to model the org chart (departments, regions, manager/subordinate structure) and permission sets to grant concrete object, field, and system capabilities.

System objects

ObjectPurpose
sys_positionPosition definition (flat — no hierarchy)
sys_user_positionA user's assignment to a position
sys_position_permission_setPermission sets distributed through a position
sys_business_unitOrg-chart tree used for hierarchy and subtree sharing
sys_business_unit_memberA user's membership in a business unit (function_in_business_unit)

Writes to the RBAC link tables (sys_user_position, sys_position_permission_set, sys_user_permission_set, sys_permission_set) require tenant-level admin rights or a delegated-admin scope — plain CRUD grants on those tables are not sufficient.

Audience anchors: everyone and guest

Two system-managed positions are seeded in every deployment:

AnchorHeld by
everyoneEvery authenticated principal, implicitly
guestSessionless (anonymous) HTTP principals only

Bind a permission set to everyone to grant a baseline to all signed-in users. Bindings are additive, and the platform refuses to bind high-privilege sets (View All / Modify All, delete/purge/transfer, system permissions, wildcards) to these anchors.

guest grants nothing. Anonymous access to object data is denied on every HTTP surface (ObjectStack 17.0), and no binding on the guest anchor gives an anonymous caller a permission set (ObjectStack 17.6). Open something to anonymous visitors by declaring the surface instead — a public form or a share link — each of which authorizes only what it declares.

The configured baseline permission set (fallbackPermissionSet, default member_default) applies through the same everyone binding path. Note that since ObjectStack 14.2 the member baseline no longer includes delete — record deletion must be granted explicitly per object through position-distributed permission sets.

A caller with no permission set gets the deny baseline (ObjectStack 17.6). A request that resolves no permission set at all — an anonymous request, or one naming only sets that do not exist — is refused every object with 403 PERMISSION_DENIED. It is not served a field gated by requiredPermissions (or is served it masked, if the field declares a maskingRule), and cannot filter, sort, group or write on one. Signed-in users are unaffected as long as a baseline set is configured — the default, member_default, always resolves for them.

Deactivating a position

A position's Deactivate action takes away everything it confers, immediately (ObjectStack 17.1):

  • it distributes none of its permission sets, and its name leaves the holders' current_user.positions;
  • a sharing rule whose recipient is the position shares with nobody, and the record shares it had already granted are revoked on the next reconcile.

Deactivation stops access, not addressing: an approval step with an approver of type position still routes to the holders of a deactivated position. A position whose active value is empty is unaffected — only an explicit deactivation counts.

Before ObjectStack 17.1 the switch was inert: a deactivated position kept granting. Upgrading past it revokes that access on live data, so re-activate any deactivated position that is still meant to grant before you upgrade.

Effective-dated assignments

Position and permission-set assignments carry optional valid_from / valid_until windows (half-open, UTC; null means unbounded). Expired grants stop resolving immediately — useful for temporary coverage, contractors, and certification-bound access. Each grant can record a reason and, for delegations, delegated_from.

A position marked delegatable: true allows its current holders to self-delegate it to another user for a bounded window (a future valid_until capped at 30 days, mandatory reason). Positions that distribute admin-scoped permission sets can never be delegatable.

Keep a small, stable set of function-shaped positions:

Sales Manager
Sales Representative
Support Manager
Support Agent

Model the org chart as business units:

Sales
  ├─ EMEA
  └─ AMER
Support

Then attach permission sets to positions for capabilities:

Sales Manager position
  -> CRM User
  -> Sales Manager Access
  -> Report Viewer

This keeps positions stable while permissions evolve independently.

Avoid

  • one position per individual user;
  • duplicating every permission inside every position;
  • using position names as business-logic checks;
  • rebuilding hierarchy on positions — subtree visibility belongs to business units and record sharing;
  • granting broad access through manager positions when record sharing would be more precise.

Migrating from roles (pre-13)

If you are upgrading metadata authored against ObjectStack 12 or earlier:

LegacyCurrent
sys_role / sys_user_role / sys_role_permission_setsys_position / sys_user_position / sys_position_permission_set
defineRole / RoleSchema (with parent)definePosition / PositionSchema (flat)
Metadata kind role or profileposition
Sharing recipient role / role_and_subordinatesposition / unit_and_subordinates
PermissionSetSchema.isProfileRemoved — isDefault marks install-time suggestions

Role hierarchies must be re-modeled as business-unit trees. os lint flags leftover role vocabulary via the security-role-word rule.