Skip to content

HYPERFLEET-1165 - docs: add multi-tenant identity and authz design (DRAFT)#189

Open
pnguyen44 wants to merge 1 commit into
openshift-hyperfleet:mainfrom
pnguyen44:HYPERFLEET-1165
Open

HYPERFLEET-1165 - docs: add multi-tenant identity and authz design (DRAFT)#189
pnguyen44 wants to merge 1 commit into
openshift-hyperfleet:mainfrom
pnguyen44:HYPERFLEET-1165

Conversation

@pnguyen44

@pnguyen44 pnguyen44 commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Summary

HYPERFLEET-1165

Design document for adding multi-tenant resource isolation to HyperFleet. Evaluates two paths: OPA-based authorization (Path A) and JWT claim mapping with DAO-layer filtering (Path B). Includes recommendations for Sentinel/Adapter identity bypass and gateway vs application-layer boundaries.

@openshift-ci
openshift-ci Bot requested review from Ruclo and vkareh July 20, 2026 21:40
@openshift-ci

openshift-ci Bot commented Jul 20, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign jsell-rh for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Summary by CodeRabbit

  • Documentation
    • Updated the glossary with the latest “Last Updated” date and added entries for system identity, tenant claims, and tenant identifiers.
    • Added a new design document covering multi-tenant identity and authorization, including enforcement options, recommended implementation approach, JWT tenant-scoping behavior, internal service bypass handling, and defense-in-depth considerations.

Walkthrough

Adds a multi-tenant identity and authorization design covering OPA middleware hooks, multi-issuer JWT claim mapping, tenant_id persistence and DAO filtering, system-identity bypasses, service boundaries, and gateway responsibilities. It records sizing decisions and open questions, and adds glossary definitions for system identity, tenant_claim, and tenant_id.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: ruclo, vkareh

🚥 Pre-merge checks | ✅ 11
✅ Passed checks (11 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the change set: a draft docs-only design for multi-tenant identity and authorization.
Description check ✅ Passed The description is aligned with the PR and accurately describes the multi-tenant authz design document.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Sec-02: Secrets In Log Output ✅ Passed PASS: Only two Markdown files changed; direct scans found no slog/logr/zap/fmt.Print* log statements with token/password/credential/secret. No CWE-532 exposure.
No Hardcoded Secrets ✅ Passed Docs-only changes; no hardcoded secrets, embedded credentials, or literal apiKey/secret/token/password assignments found. CWE-798/CWE-259.
No Weak Cryptography ✅ Passed Docs-only change; no crypto code, weak primitives, custom crypto, or secret comparisons found in changed files. No CWE-327/CWE-208 issue.
No Injection Vectors ✅ Passed PR only changes Markdown docs; diff adds no code paths or sink patterns (SQL/exec/template/yaml), so no CWE-89/78/79/502 injection vector is introduced.
No Privileged Containers ✅ Passed PASS: Only Markdown docs changed; no Kubernetes/OpenShift manifests, Helm templates, or Dockerfiles, so no privileged settings (CWE-250) were introduced.
No Pii Or Sensitive Data In Logs ✅ Passed PASS: PR is docs-only; the diff adds no slog/logr/zap/fmt.Print logging statements or raw request/response body logs.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@hyperfleet/docs/glossary.md`:
- Around line 66-68: Update the tenant_id glossary entry to state that it is
server-owned and immutable: clients must not supply or modify it, updates must
preserve the existing tenant, and system identities must not create tenantless
or cross-tenant resources. Retain the existing creation and DAO filtering
description while making clear that filtering does not replace write-path
enforcement.

In `@hyperfleet/docs/multi-tenant-identity-authz-design.md`:
- Line 330: Update the TODO in the multi-tenant identity authorization design
document to include the tracked ticket ID for filling it after POC results are
available, using the project’s required ticket format.
- Line 299: Update the “Trust contract (if gateway-first is adopted later)”
section to remove shared internal network access as an acceptable authentication
mechanism. Require authenticated gateway-to-API mTLS or a cryptographically
signed tenant header, explicitly strip or reject client-supplied X-Tenant-ID
values, and reject direct API traffic whenever gateway-derived identity is
required.
- Around line 118-120: Update the authorization design and implementation around
OPA availability to require fail-closed behavior for all protected operations,
removing configurable fail-open access. Define explicit OPA request timeouts and
bounded retries, and restrict authorization bypasses to health endpoints only;
flag the security-boundary bypass in the relevant documentation.
- Around line 159-161: Update the “Claim-to-tenant resolution” design so raw
claim values cannot collide across issuers: require an issuer-qualified tenant
identity key or a mandatory raw-to-canonical tenant mapping with uniqueness
constraints. Replace the current assumption that raw claim values may be stored
directly as tenant_id, and document the selected resolution behavior for all
issuers.
- Around line 216-231: Update the Shared Sentinel with system identity design
and its corresponding mitigation section to require explicit validation for
system tokens: a dedicated internal audience, exact service-account
subject/workload binding, approved issuer and signing algorithm allowlists,
short token lifetimes, and rejection of direct external access. State that token
rotation is insufficient unless the API validates the projected service-account
token format and issuer.
- Around line 159-163: Update the Claim-to-tenant resolution and tenant-scoped
middleware design to explicitly reject tokens when the configured tenant_claim
is missing, empty, or malformed, returning the documented consistent 401/403
response. Ensure rejection occurs before any DAO access and never falls back to
an unscoped query; align the behavior with the existing missing-claim contract
in the upgrade guide.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 8e94c46e-9d58-46c1-97ab-035c05a37947

📥 Commits

Reviewing files that changed from the base of the PR and between a563e7d and 19e835f.

📒 Files selected for processing (2)
  • hyperfleet/docs/glossary.md
  • hyperfleet/docs/multi-tenant-identity-authz-design.md
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • openshift-hyperfleet/architecture (manual)
  • openshift-hyperfleet/hyperfleet-api (manual)
  • openshift-hyperfleet/hyperfleet-sentinel (manual)
  • openshift-hyperfleet/hyperfleet-adapter (manual)
  • openshift-hyperfleet/hyperfleet-broker (manual)

Comment thread hyperfleet/docs/glossary.md Outdated
Comment thread hyperfleet/docs/multi-tenant-identity-authz-design.md Outdated
Comment thread hyperfleet/docs/multi-tenant-identity-authz-design.md Outdated
Comment thread hyperfleet/docs/multi-tenant-identity-authz-design.md
Comment thread hyperfleet/docs/multi-tenant-identity-authz-design.md
Comment thread hyperfleet/docs/multi-tenant-identity-authz-design.md Outdated
Comment thread hyperfleet/docs/multi-tenant-identity-authz-design.md Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@hyperfleet/docs/multi-tenant-identity-authz-design.md`:
- Around line 193-203: Update the Query Filtering recommendation and related
tenant-scoped identity design to require binding tenant_id on writes from
authenticated context, not caller input alone. Validate at HTTP handlers, CLI
parsers, and webhook receivers; reject caller-supplied mismatches, keep
tenant_id immutable for tenant-scoped identities, and allow changes only through
explicit system authorization.
- Around line 313-330: The recommended application-only Go middleware must
perform full JWT validation at the HTTP boundary, including signature, issuer,
audience, lifetime, and allowed algorithm checks; do not limit these checks to
the future gateway-first option or rely on signature-only validation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: aa76dc1e-4080-40ed-bc21-2b9edee50e05

📥 Commits

Reviewing files that changed from the base of the PR and between 83cdb05 and 3466f0e.

📒 Files selected for processing (2)
  • hyperfleet/docs/glossary.md
  • hyperfleet/docs/multi-tenant-identity-authz-design.md
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • openshift-hyperfleet/architecture (manual)
  • openshift-hyperfleet/hyperfleet-api (manual)
  • openshift-hyperfleet/hyperfleet-sentinel (manual)
  • openshift-hyperfleet/hyperfleet-adapter (manual)
  • openshift-hyperfleet/hyperfleet-broker (manual)
🚧 Files skipped from review as they are similar to previous changes (1)
  • hyperfleet/docs/glossary.md

Comment on lines +193 to +203
### Query Filtering

Options:

| Approach | Pros | Cons |
|----------|------|------|
| Implicit `WHERE tenant_id = ?` on all queries | Safer (can't forget it), enforced at DAO layer | Less flexible, internal services (Sentinel, Adapter) need a bypass |
| Explicit query parameter | More flexible, caller decides scope | Easy to forget, creates a security hole if someone omits it |
| PostgreSQL Row-Level Security (RLS) | Database-level enforcement as safety net | Requires setting a session variable per request, adds complexity to connection pooling |

**Recommendation:** Use implicit filtering at the DAO layer. It prevents accidental cross-tenant data leaks because developers can't forget the WHERE clause. Internal services that need cross-tenant access (Sentinel, Adapter) would use a bypass mechanism (see Sentinel/Adapter Identity section). RLS can be layered on top as defense-in-depth but should not be the sole mechanism.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Bind tenant_id on writes, not only reads.

DAO filtering prevents cross-tenant reads, but the design does not define how create/update requests protect resource ownership. A caller-supplied tenant_id could create or update another tenant’s resource. Derive it from authenticated context, reject mismatches, and make it immutable for tenant-scoped identities; permit changes only through explicit system authorization. CWE-639, CWE-915.

As per path instructions, validate input at system boundaries (HTTP handlers, CLI parsers, webhook receivers).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@hyperfleet/docs/multi-tenant-identity-authz-design.md` around lines 193 -
203, Update the Query Filtering recommendation and related tenant-scoped
identity design to require binding tenant_id on writes from authenticated
context, not caller input alone. Validate at HTTP handlers, CLI parsers, and
webhook receivers; reject caller-supplied mismatches, keep tenant_id immutable
for tenant-scoped identities, and allow changes only through explicit system
authorization.

Source: Path instructions

Comment on lines +313 to +330
### Option: Application-only (current approach)

Pros:

- Portable. Works anywhere without infrastructure dependencies.
- Single source of truth for auth logic (Go middleware).
- Testable without infrastructure: no gateway to simulate in unit/integration tests.

Cons:

- Every request (including invalid ones) reaches the application before being rejected.
- If HyperFleet adds more services in the future, each would reimplement the same auth logic.

### Recommendation

**Application-only for now.** JWT validation and tenant extraction both happen in Go middleware. Only the API receives external traffic; Sentinel and Adapter are internal-only. There's no multi-service gateway benefit. The middleware approach is portable and doesn't depend on NetworkPolicy for security (the JWT signature itself prevents spoofing).

Gateway-layer validation can be added later as a performance optimization without changing application code (defense-in-depth, not replacement).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Apply full JWT validation to the recommended application-only path.

The explicit signature, issuer, audience, lifetime, and algorithm checks are scoped to the future gateway-first option, while the current Go middleware is the trust boundary. Require the same checks in application middleware; signature-only validation can accept tokens intended for another audience or issuer. CWE-347, CWE-287.

As per path instructions, validate input at system boundaries (HTTP handlers, CLI parsers, webhook receivers).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@hyperfleet/docs/multi-tenant-identity-authz-design.md` around lines 313 -
330, The recommended application-only Go middleware must perform full JWT
validation at the HTTP boundary, including signature, issuer, audience,
lifetime, and allowed algorithm checks; do not limit these checks to the future
gateway-first option or rely on signature-only validation.

Source: Path instructions

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.

1 participant