ui calculator
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
# Secure Exchange Architecture
|
||||
|
||||
## Purpose
|
||||
|
||||
This document fixes the transport-level secure exchange model between client and server.
|
||||
It is the starting point for implementing authenticated device sessions, signed requests/responses, and anti-replay protection.
|
||||
|
||||
## Main Principles
|
||||
|
||||
- No browser cookies are used.
|
||||
- Authentication is device-session based.
|
||||
- Each device/session is unique and independently revocable.
|
||||
- There are no short-lived access tokens or refresh-token flows in the main design.
|
||||
- Requests are authenticated by client-side signatures.
|
||||
- Responses are authenticated by server-side signatures.
|
||||
- Transport integrity and freshness are verified before payload is processed.
|
||||
|
||||
## Device Session Model
|
||||
|
||||
After successful login through e-mail code:
|
||||
|
||||
1. client generates an asymmetric key pair
|
||||
2. private key remains on the client device
|
||||
3. public key is registered on the server
|
||||
4. server creates a persistent `device_session`
|
||||
5. client stores:
|
||||
- `device_session_id`
|
||||
- private key
|
||||
|
||||
The server stores at least:
|
||||
|
||||
- `device_session_id`
|
||||
- `user_id`
|
||||
- client public key
|
||||
- session status
|
||||
- revoke metadata
|
||||
|
||||
## Key Storage
|
||||
|
||||
### Native Clients
|
||||
|
||||
Private key should be stored in platform secure storage.
|
||||
|
||||
### Browser / WASM Clients
|
||||
|
||||
Private key should be created and used through WebCrypto.
|
||||
Non-exportable key storage is preferred.
|
||||
Loss of browser storage is acceptable and means re-login is required.
|
||||
|
||||
## Request Structure
|
||||
|
||||
Each authenticated request logically contains:
|
||||
|
||||
- `payload_bytes`
|
||||
- `request_envelope`
|
||||
- `signature`
|
||||
|
||||
### Request Envelope
|
||||
|
||||
Minimal required fields:
|
||||
|
||||
- `protocol_version`
|
||||
- `device_session_id`
|
||||
- `message_type`
|
||||
- `timestamp_ms`
|
||||
- `request_id`
|
||||
- `payload_hash`
|
||||
|
||||
### Request Signing Input
|
||||
|
||||
The client signs canonical bytes built from:
|
||||
|
||||
- request domain marker, for example `myapp-request-v1`
|
||||
- `protocol_version`
|
||||
- `device_session_id`
|
||||
- `message_type`
|
||||
- `timestamp_ms`
|
||||
- `request_id`
|
||||
- `payload_hash`
|
||||
|
||||
`payload_hash` should be computed from raw `payload_bytes`.
|
||||
|
||||
The goal is to bind the signature to:
|
||||
|
||||
- the concrete device session
|
||||
- the concrete message type
|
||||
- the concrete payload
|
||||
- a fresh request instance
|
||||
|
||||
## Response Structure
|
||||
|
||||
Each server response logically contains:
|
||||
|
||||
- `payload_bytes`
|
||||
- `response_envelope`
|
||||
- `signature`
|
||||
|
||||
### Response Envelope
|
||||
|
||||
Minimal required fields:
|
||||
|
||||
- `protocol_version`
|
||||
- `request_id`
|
||||
- `timestamp_ms`
|
||||
- `result_code`
|
||||
- `payload_hash`
|
||||
|
||||
### Response Signing Input
|
||||
|
||||
The server signs canonical bytes built from:
|
||||
|
||||
- response domain marker, for example `myapp-response-v1`
|
||||
- `protocol_version`
|
||||
- `request_id`
|
||||
- `timestamp_ms`
|
||||
- `result_code`
|
||||
- `payload_hash`
|
||||
|
||||
The client verifies the signature using a trusted server public key.
|
||||
|
||||
## Verification Order on Server
|
||||
|
||||
Before processing payload, the server/gateway must:
|
||||
|
||||
1. verify that the transport envelope is present and supported
|
||||
2. resolve `device_session_id`
|
||||
3. reject unknown or revoked sessions
|
||||
4. verify client signature using stored public key
|
||||
5. verify timestamp freshness window
|
||||
6. verify anti-replay constraints using `request_id`
|
||||
7. only then pass payload to business processing
|
||||
|
||||
## Verification Order on Client
|
||||
|
||||
Before accepting response payload, the client must:
|
||||
|
||||
1. verify server signature
|
||||
2. verify `request_id` matches the corresponding request
|
||||
3. verify `payload_hash`
|
||||
4. verify timestamp freshness if applicable
|
||||
5. only then accept the response payload
|
||||
|
||||
## Anti-Replay Model
|
||||
|
||||
Transport anti-replay uses:
|
||||
|
||||
- `timestamp_ms`
|
||||
- `request_id`
|
||||
|
||||
The server accepts requests only inside an allowed time window.
|
||||
Recently seen `request_id` values must be tracked for the corresponding session and rejected on reuse.
|
||||
|
||||
This protects transport freshness.
|
||||
It does not replace business idempotency.
|
||||
|
||||
## Server Time Offset
|
||||
|
||||
Clients use server time offset instead of trusting local clock directly.
|
||||
|
||||
Expected approach:
|
||||
|
||||
- client establishes authenticated long-polling / push connection
|
||||
- server provides current server time
|
||||
- client computes local offset
|
||||
- subsequent signed requests use adjusted time
|
||||
|
||||
No extra sync request is required if push / long-polling already exists.
|
||||
|
||||
## TLS and MITM Considerations
|
||||
|
||||
### Native Clients notes
|
||||
|
||||
Native clients should use TLS pinning in addition to signed request/response exchange.
|
||||
Pinning should be based on public key / SPKI rather than leaf certificate whenever possible.
|
||||
|
||||
### Browser / WASM Clients notes
|
||||
|
||||
Real TLS pinning is not available in the browser in the same way as in native clients.
|
||||
Browser clients still use the signed request/response model, but browser-managed TLS remains the platform limitation.
|
||||
|
||||
## Threat Model Boundaries
|
||||
|
||||
This design protects against:
|
||||
|
||||
- request/response tampering in transit
|
||||
- replay of previously seen transport messages inside the protected window
|
||||
- use of unknown or revoked device sessions
|
||||
- forged server responses without server signing key
|
||||
- forged client requests without client signing key
|
||||
|
||||
This design does not guarantee that a legitimate user cannot generate their own valid requests from their own client environment.
|
||||
That is handled by server-side business validation and authorization.
|
||||
|
||||
## Architectural Notes
|
||||
|
||||
- Transport authentication and business authorization are separate concerns.
|
||||
- Signed transport proves message origin and integrity.
|
||||
- Business services must still validate command correctness, ownership, permissions, and state transitions.
|
||||
- Transport `request_id` is not the same as business idempotency key.
|
||||
|
||||
## Recommended Outcome
|
||||
|
||||
The system should treat the secure exchange layer as the mandatory outer contract for all authenticated traffic.
|
||||
Only after successful transport validation may payload be routed to business logic.
|
||||
Reference in New Issue
Block a user