CONTEXT_limited_mode.md

Limited Mode (Web) — Project Context

Purpose

This context document captures the current design and implementation context for Limited Mode in the web UI.

Primary goal: allow non-admin users to access a strictly scoped subset of tenancy analysis data, while ensuring backend enforcement prevents data disclosure through direct API payload tampering.

This is a project/context artifact (architecture + behavior + acceptance), not a task-focused end-user quickstart.


Problem Statement

Original web auth was effectively binary (authenticated vs not authenticated), without explicit modeling for:

  • role (admin vs limited)

  • compartment scope

  • identity-domain scope

This allowed authenticated users to reach broad data surfaces once tenancy data was loaded.

Limited Mode introduces tenancy-bound limited keys and mandatory server-side scoping to enforce least privilege.


Business Rules (Current)

  1. Limited profiles are per tenancy.

  2. Limited users are scoped to a compartment root path (including descendants).

  3. Limited users may have an allow-list of identity domains.

  4. Empty allowed identity domains means no IAM detail access:

    • users / groups / dynamic groups should return empty sets.

  5. Policy statement text may still contain principal names.

  6. Limited users must not access admin/index/load/cache surfaces.

  7. Simulation is available for limited users only when policy_scope_mode=include_relevant_ancestors.

  8. Prospective statements are view-only for limited users:

    • no create/edit/replace/validate/builder access

    • only scoped prospective rows are visible


Security Model

Roles

  • Admin

    • Authenticated with runtime admin key.

    • Can load/cache tenancy data, manage limited profiles, and use full surfaces.

  • Limited

    • Authenticated using an activated limited key mapped to a profile.

    • Access restricted to scoped analysis pages.

Session Contract (Target)

{
  "authenticated": true,
  "auth_mode": "limited",
  "auth_key_fp": "...",
  "limited_scope": {
    "profile_id": "...",
    "tenancy_ocid": "ocid1.tenancy...",
    "compartment_root_paths": ["ROOT/Finance"],
    "policy_scope_mode": "strict_descendants",
    "allowed_identity_domains": ["Default", "CorpDomainA"]
  }
}

Key Storage Rules

  • Never persist plaintext limited keys.

  • Persist key hash/fingerprint only (e.g., SHA-256).

  • Newly generated key material is shown once at creation/activation time.

Runtime Activation Lifecycle

Profile definitions may persist, but limited keys are runtime-scoped credentials:

  • Admin activates/generates limited keys during an admin session.

  • Activated limited keys are valid only for current process runtime.

  • Restart clears active limited keys by default.

  • Admin must re-activate/re-generate after restart.

This mirrors runtime admin-key behavior and reduces long-lived credential exposure.

Phase-1 Operational Decisions

  • Existing admin startup runtime key logging remains unchanged.

  • Limited profile definitions persist under tenancy settings.

  • Runtime activation state is non-persistent (inactive at startup).

  • Admin utility controls include:

    • activate limited profile key

    • deactivate limited profile key

    • display active key material in admin utility view

  • While profile key is active, scope criteria controls are read-only in UI.

  • When inactive, scope criteria become editable.


UX Requirements (First Pass)

Admin Utility Surface (Limited Scope Management)

Admin-only page/section with at least:

  • list limited profiles for current loaded tenancy

  • create/edit profile label, compartment root, allowed identity domains

  • activate/generate runtime limited key (display once)

  • deactivate runtime key(s)

  • enable/disable profile definition

Visibility rules:

  • visible only to admin sessions

  • hidden/blocked for limited sessions

  • excluded from limited-mode navigation

Limited Landing Experience

On limited login, route to a simplified landing card indicating:

  • scoped-data banner

  • tenancy context

  • scoped compartment root (descendants included)

  • allowed identity domains (or explicit none)

  • full admin/simulation/full-data unavailable warning

  • instruction to contact admins for broader scope

Masthead

Display app version plus role badge:

  • Admin

  • Limited


API Enforcement Strategy (Critical)

Enforcement is backend-side on every relevant route; UI hiding is not security.

Core Predicates

For limited sessions, returned records must satisfy:

  1. Compartment predicate: effective/policy path within scoped subtree.

  2. Domain predicate (IAM detail only): entity domain in allow-list.

First-Pass Route Matrix

Route

Limited behavior

POST /filter/policies

Return statements only within scoped subtree

POST /filter/policies/by-subjects

Same compartment scoping; expansions remain scoped

GET /entities/users

Allowed domains only; empty if domain list empty

GET /entities/groups

Allowed domains only; empty if domain list empty

GET /entities/dynamic-groups

Allowed domains only; empty if domain list empty

Resource-principal analysis routes

Apply compartment subtree scoping

Admin/load/cache routes

Deny (403) for limited

GET /simulation/context-options

Allowed only when policy_scope_mode=include_relevant_ancestors; otherwise 403

POST /simulation/statements

Same as above; compartment/domain scope enforced

POST /simulation/variables

Same as above

POST /simulation/run

Same as above; compartment/domain scope enforced

GET /simulation/history*

Same as above

POST /simulation/prospective-preview

Same as above; returns scoped prospective-only rows

GET /prospective/statements

Limited users: scoped read-only rows only

/prospective/statements/validate|replace

Admin-only

/prospective/builder/*

Admin-only

Policy Visibility Mode

Limited profiles include policy visibility mode:

  • policy_scope_mode: "strict_descendants" | "include_relevant_ancestors"

Semantics:

  • strict_descendants (default)

    • include scoped root and descendants only

  • include_relevant_ancestors

    • also include relevant ancestor-scope statements affecting scoped subtree

This applies to policy statement visibility only; IAM detail visibility remains controlled by allowed_identity_domains.

Anti-Tamper Requirement

If limited users craft broadened API payloads, backend must still:

  • enforce scope

  • ignore out-of-scope expansions

  • return only scoped rows (or empty)


Data Model (Limited Profiles)

Legacy-style persisted shape

{
  "limited_access_profiles": [
    {
      "profile_id": "uuid",
      "label": "Finance auditors",
      "enabled": true,
      "tenancy_ocid_hash": "sha256(...)",
      "compartment_root_path": "ROOT/Finance",
      "allowed_identity_domains": ["Default"],
      "key_hash": "sha256(limited_key)",
      "created_at": "ISO8601",
      "updated_at": "ISO8601"
    }
  ]
}

Preferred tenancy-keyed persistence

{
  "limited_access_by_tenancy": {
    "ocid1.tenancy.oc1..aaaa...": {
      "profiles": [
        {
          "profile_id": "uuid",
          "label": "Finance auditors",
          "enabled": true,
          "compartment_root_path": "ROOT/Finance",
          "policy_scope_mode": "strict_descendants",
          "allowed_identity_domains": ["Default"],
          "created_at": "ISO8601",
          "updated_at": "ISO8601"
        }
      ]
    }
  }
}

Notes:

  • Persistence should be tenancy-keyed (tenancy OCID preferred).

  • tenancy_ocid_hash protects against wrong-tenancy key usage.

  • allowed_identity_domains: [] is valid and means no IAM detail visibility.

  • Runtime key activation state is non-persistent and references profile IDs.


Implementation Phases

Phase 1 (Current Scope)

  1. Role-aware session model (admin / limited).

  2. Limited profile CRUD backend + admin management page.

  3. Limited login resolving profile + scope.

  4. Server-side scope guards on first-pass endpoints.

  5. Limited landing card + role badge + nav restrictions.

  6. Hard blocks for admin/load/cache in limited mode.

  7. Conditional simulation access for limited mode when policy_scope_mode=include_relevant_ancestors.

  8. Prospective statements read-only visibility for limited mode across Policy Analysis and Simulation.

Phase 2 (Future)

  • Extended reporting under scope.

  • Key expiration/rotation automation.


Acceptance Criteria (Phase 1)

  1. Admin can create limited profile (key, compartment root, domain allow-list).

  2. Limited key login yields limited scoped session + landing experience.

  3. Limited users cannot access admin/index/load/cache routes.

  4. Limited users can access simulation routes only when policy_scope_mode=include_relevant_ancestors.

  5. Limited users have no prospective mutation capabilities; scoped prospective visibility is read-only.

  6. Policy/analysis outputs are scope-limited.

  7. Empty domain allow-list produces zero IAM detail rows.

  8. Crafted API payloads cannot reveal out-of-scope data.


Test Checklist

  • Create limited profile with non-root compartment + one allowed domain.

  • Login with limited key; verify role badge + scope warning card.

  • Verify allowed pages work; blocked pages return 403/redirect.

  • Verify simulation is enabled only for include_relevant_ancestors profiles.

  • Verify policy routes exclude statements above scope root.

  • Verify users/groups/dynamic-groups restricted to allowed domains.

  • Verify empty-domain profile returns empty IAM endpoint results.

  • Verify limited users can only view (not edit/build/replace) prospective statements.

  • Attempt API payload tampering; verify scoped-only outputs.


Risks / Notes

  • Scope filtering should be centralized to avoid route drift.

  • UI should clearly signal that empty results may be scope-driven.

  • Simulation is conditionally enabled; route guard drift would be a leak vector, so _require_simulation_access must remain the single enforcement gate.