# Customer isolation and access

> Historical design requirements: consult [chapter 30](30-current-architecture.md) for the current implementation and outstanding work.

## Non-negotiable ownership boundary

Only a SuperAdmin can create a customer or assign, unassign or transfer a device between customers. Customer administrators may manage devices already assigned to their customer, including groups and merchant placement; they cannot acquire devices from global inventory by entering a serial number.

Every tenant-owned record carries CustomerId. Relationship constraints include the customer key so a group, device, schema, application or job cannot point across customers. Global device inventory is a separately authorized aggregate. CustomerId supplied by a browser is an untrusted selector, never proof of membership.

## Proposed permission matrix

| Action | SuperAdmin | CustomerAdmin | FleetOperator | SchemaDesigner | Auditor |
| --- | --- | --- | --- | --- | --- |
| Create/suspend customer | Yes | No | No | No | No |
| Assign/transfer devices to customer | Yes | No | No | No | No |
| Manage customer users | Yes, scoped | Own customer | No | No | No |
| View fleet/telemetry | Explicit customer scope | Own customer | Own customer | As granted | Own customer |
| Groups/tags/placement | Scoped permission | Yes | As granted | No | No |
| Reboot/message | Scoped permission | Yes | Yes | No | No |
| Block/unblock | Scoped permission | Yes | Separate grant | No | No |
| Start remote control | Separate grant | Separate grant | Separate grant | No | No |
| Upload/release software | Scoped permission | Yes | Separate grant | No | No |
| Edit/publish schemas | Scoped permission | Yes | No | Yes | No |
| Edit/push parameters | Scoped permission | Yes | Separate grants | As granted | No |
| Read/export audit | Scoped permission | Yes | As granted | As granted | Yes |

SuperAdmin is a platform role; customer roles are membership-scoped. Membership management cannot grant SuperAdmin or rights the actor is not allowed to delegate. High-impact operations can use a proposed bank-configurable approval policy; at minimum preview target count and require a reason for block, transfer and remote support. An approval is invalidated if targets or payload change.

## Claims, cookies and session

The current release uses the local managed identity store. Passwords are BCrypt hashes. Optional MFA uses RFC-compatible six-digit TOTP codes, five-minute pre-session challenges and ten one-time recovery codes. MFA secrets are encrypted with an installation-specific account security key held in the machine-protected DPAPI secrets file. Enabling or disabling MFA requires the current password and a valid TOTP/recovery factor. Federation with a bank identity provider remains a future option.

Forgotten-password recovery is optional and SMTP-backed. The public request returns the same result for every address, limits repeated issuance, and delivers a random single-use token only for an enabled matching account. Tokens expire after 30 minutes, are stored only as SHA-256 hashes, and are invalidated after use. Resetting a password revokes active sessions but preserves MFA. SMTP credentials are DPAPI-protected. When email recovery is not configured, customer or platform administrators perform an authorized password reset from user administration.

Claims carry user ID and customer-scoped feature permissions. A CustomerId claim is only context and is revalidated. The portal uses secure HttpOnly cookies, strict SameSite policy and antiforgery validation on state-changing MVC actions. No authenticated session is created until an enabled MFA account completes its second factor.

Session stores convenience state, not permissions, commands or unsaved durable business drafts. Use distributed cache and a protected shared key ring. Session loss prompts customer reselection; it must never select another customer silently. ASP.NET Core session is ephemeral and non-locking, so concurrent tabs cannot rely on a shared selected-customer value for authorization. Explicit customer routes plus request context avoid cross-tab customer-switch errors. [Microsoft session guidance](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/app-state?view=aspnetcore-8.0).

DataService verifies service identity and signed actor delegation, and resolves current permissions server-side. Plain metadata such as `x-customer-id` or `x-user-id` is insufficient. Worker identities have narrowly scoped ingest/dispatch privileges and cannot impersonate a portal administrator. Revocation and customer suspension are checked before sensitive writes, dispatch and remote-session admission; permission caches must be versioned and invalidated.

## Repository and resource enforcement

- Queries filter by CustomerId and resource ID together; inaccessible resources return a consistent not-found response.
- Composite foreign keys enforce same-customer device/group/application/schema relationships.
- Tenant context appears in cache keys, object metadata, work items, audit records and transport mappings.
- Export jobs recheck permissions at execution and download time; temporary URLs expire quickly.
- No global wildcard device broadcast is available to a customer operation.
- Database row-level security is optional defense in depth. If adopted, test session-context cleanup with pooled connections; it does not replace scoped queries.

## Safe customer transfer

1. SuperAdmin requests transfer with source/target customer, expected assignment version and reason. Lock device assignment against concurrent changes.
2. Quarantine the device; cancel undispatched work, prevent new work, terminate remote sessions and invalidate old delivery grants.
3. Revoke credentials and old broker/shadow access; clear pending transport state. Require reset or verified removal of customer data and credentials on the terminal.
4. Keep transfer Pending until cleanup is verified. An offline device cannot be activated under the new customer merely by updating SQL.
5. Atomically close assignment history, increment AssignmentEpoch and create new assignment. Clear old groups, tags and placement; retain old audit and historical telemetry under the source customer.
6. Issue fresh enrollment authorization and credentials. Activate for the target customer only after identity and cleanup verification.
7. Reject old acknowledgements, tickets and messages by assignment epoch. Historical records are not re-labeled as belonging to the new customer.

Retirement uses the same credential/work/session shutdown rules without a new assignment.

## Remote support and sensitive data

Issue short-lived, one-time connection tickets bound to customer, device, assignment epoch, actor, session and permitted mode (view/control). Validate origin and membership, audit start/stop, expire idle sessions and revoke immediately on permission loss or transfer. Ticket material must not appear in logs or long-lived URLs; prefer authenticated same-origin admission and an initial ticket message before any frames flow.

Payment credentials, PIN data, PAN/track data and cryptographic key material must never enter ordinary telemetry, screen recordings, logs or schema exports. Screen masking and payment-screen suppression require terminal-agent support; unsupported models cannot be offered unrestricted remote control over sensitive screens. No arbitrary terminal shell is included. Generic secret parameter fields use secret references and write-only replacement; payment key injection remains a separate controlled subsystem.

## Isolation acceptance tests

For every sensitive endpoint and RPC: customer A cannot read, edit, export, command or connect to customer B's resources using guessed IDs, mixed parent/child IDs, forged metadata, stale membership or bulk selections. Test the same cases through the broker, downloads, remote tickets and delayed worker jobs. Verify last-admin protection, concurrent transfers, credential revocation and cross-tab customer changes.
