Security Model
EdgeInteract handles sensitive Human-in-the-Loop operations — approval decisions, data access authorizations, and user confirmations. Security is built into the interaction lifecycle at every stage.
Interaction Targeting — Who Sees What
Every InteractionRequest has a targetUserId. The EdgeInteract server guarantees that only the targeted user (or users with the targeted role) receives the interaction on their session. The topic interactions.{userId} is per-user and access-controlled at the EdgeStream layer.
Single-User Targeting
When targetUserId is a specific user ID, the interaction is published exclusively to that user's EdgeStream topic. No other user can subscribe to or receive the message.
Role Targeting
When targetUserId is a role key (e.g., "role:finance-managers"), EdgeInteract resolves the role to a list of user IDs server-side and publishes to each user's individual topic. Users receive the interaction only if they have the role at the time of publication.
Response Authorization — Who Can Respond
The server validates the respondent's identity when an InteractionResponse arrives on the callback topic. Specifically:
- The
respondedByfield in the response must match a user who was legitimately targeted by the original request - The session ID is verified against the authenticated EdgeStream session
- Unsigned or spoofed responses are rejected — the WebSocket connection requires authentication
- A response can only be submitted once per
interactionId— duplicate responses are discarded
Topic-Level Access Control
EdgeStream enforces access control at the topic level. The EdgeInteract topics follow this pattern:
| Topic | Who Can Subscribe | Who Can Publish |
|---|---|---|
interactions.{userId} | Authenticated sessions for that user only | EdgeInteract server (never the client) |
interactions.callback.{interactionId} | EdgeInteract server only | Authenticated session of the respondent |
Payload Security
The interaction payload travels over the WebSocket connection, which is always TLS-encrypted. However, because the payload may contain sensitive business context (invoice amounts, personal data), follow these rules:
- Do not include raw credentials or secrets in the interaction payload — use reference IDs
- Minimize payload size — include only what the user needs to make the decision
- Sensitive field values should use display-safe representations (e.g.,
"****1234"for account numbers) - The audit log records the full payload — ensure it does not contain data that should not be retained
Rate Limiting
The built-in RateLimitInteractionHook prevents flooding a user with too many interactions per time window. This protects both the user experience and the system from abuse:
// Configuration
{
"EdgeInteract": {
"RateLimiting": {
"MaxPerMinutePerUser": 5,
"MaxConcurrentPerUser": 10,
"BurstAllowance": 2
}
}
}
Interactions that exceed the rate limit are rejected with an InteractionRateLimitException on the server before they reach the transport layer.
Audit Trail
Every interaction generates an audit record with:
- The full
InteractionRequest(requestor, target, type, payload, timestamp) - The full
InteractionResponse(respondent, outcome, data, timestamp) - Or the
InteractionTimeoutif no response arrived - The EdgeStream session ID of the responding session
- IP address and user agent of the responding session (via EdgeStream session metadata)
Audit records are retained for the configured retention period (default 90 days) and are immutable — they cannot be deleted via the normal API.
Security Checklist
| Requirement | How EdgeInteract Satisfies It |
|---|---|
| Only the right user sees the interaction | Per-user topics, access-controlled at EdgeStream layer |
| Only authorized users can respond | Session authentication, respondent validation, single-response enforcement |
| Responses cannot be spoofed | WebSocket connection requires authentication; session ID validated |
| Users cannot be flooded | Rate limit hook enforces max interactions per minute per user |
| Full audit trail for compliance | Audit hook logs every request/response pair with metadata |
| Payload is encrypted in transit | EdgeStream requires TLS; all WebSocket traffic is encrypted |