FDC3 Security provides standardized mechanisms for signed context, encrypted private channels, and verified user identity across FDC3-enabled applications.
This package implements the @experimental FDC3 Security & Identity specification, focusing on the separation of concerns between a low-trust frontend (e.g., a browser) and a high-trust backend where cryptographic private keys are managed. See the specification for the full conceptual model, use cases, and key management requirements.
All cryptographic operations that involve a private key — signing outbound context, generating symmetric encryption keys, unwrapping received JWE-wrapped keys — MUST be performed in a trusted backend (server), not in the browser frontend. This package provides FDC3Handlers, a TypeScript interface defining the contract between a frontend and its backend, together with ClientSideHandlersImpl and ServerSideHandlersImpl to implement that contract over a WebSocket.
Verification results are never placed on ContextMetadata (the wire type forwarded by the Desktop Agent). Instead, when a receiving application calls its security implementation's verification function with the received ContextMetadata, it gets back a ContextVerificationMetadata object containing:
authenticity— the result of signature verification (signed,valid,trusted,jku,kid,alg,errors)encryption— the result of decryption ('decrypted'|'cant_decrypt'|'not_encrypted')
ContextVerificationMetadata is exported from @finos/fdc3-security and is also the type used by SecurityAwareContextHandler and SecurityAwareIntentHandler.
When wrapping a context or intent handler with SignatureCheckingHandlerSupport, you must provide a handler with a three-argument signature rather than the standard two-argument ContextHandler / IntentHandler:
// Standard FDC3 handler
(context: Context, metadata: ContextMetadata | undefined) => void
// Security-aware handler — receives verification result as third argument
(context: Context, metadata: ContextMetadata | undefined, verification: ContextVerificationMetadata) => voidThis keeps ContextMetadata clean as a wire type while making the verification result conveniently available to handler logic.
The core cryptographic interfaces and implementations.
PublicFDC3Security: Interface for public-key operations — signature verification, JWT verification, symmetric key creation and encryption, key wrapping and unwrapping. Used by frontend or backend components that do not hold private keys.PrivateFDC3Security: ExtendsPublicFDC3Securitywith private-key operations — signing context, creating user identity JWTs, and decrypting asymmetrically encrypted payloads. Implementations MUST run in a trusted backend.JosePublicFDC3Security: Implementation ofPublicFDC3Securityusing thejoselibrary (JWS/JWE).JosePrivateFDC3Security: ExtendsJosePublicFDC3Securitywith private-key operations.AntiReplayChecker: Interface andDefaultAntiReplayCheckerimplementation for tracking seenjtivalues to prevent replay attacks. In production, back with a shared cache (e.g. Redis) rather than the in-memory default.ContextVerificationMetadata: The outcome of verifying a signed or encrypted context — populated locally by the security library, never sent on the wire. Containsauthenticity(signature check result) andencryption(decryption status). This type is defined here rather than in@finos/fdc3-standardbecause it is a library-computed result, not part of the FDC3 wire protocol.FDC3UserClaims: TypeScript interface for the JWT payload returned by aGetUserintent (iss,sub,aud,exp,iat,jti).FDC3SecurityAlgorithms: Configuration record for the cryptographic algorithms used (signing, key wrapping, content encryption). Defaults toEdDSA/RSA-OAEP-256/A256GCM.FDC3SecurityTimeLimits: Configuration for signature freshness and context expiry windows.
Supports the signing and verification of FDC3 messages (broadcasts and intents).
SignedBroadcastSupport/BasicSignedBroadcaster: Signs outgoing broadcasts using aPrivateFDC3Securityinstance running on the backend.SignatureCheckingHandlerSupport/BasicSignatureCheckingHandlerSupport: Wraps aSecurityAwareContextHandlerorSecurityAwareIntentHandlerso that incoming signatures are verified before the handler is called. TheContextVerificationMetadataresult is passed as the third argument to the handler.SecurityAwareContextHandler/SecurityAwareIntentHandler: Handler types that receiveContextVerificationMetadataas a third argument alongside the standardContextandContextMetadata.SignedIntentResultSupport: Signs context returned as an intent result.SignedRaiseIntentSupport/BasicSignedRaiseIntentSupport: Raises intents with a signed context and optionally verifies the signature on the returned result. Returns aVerifiedIntentResolutionwhosegetVerification()method provides theContextVerificationMetadatafor the context result, without storing it inContextMetadata.
Classes and utilities for end-to-end encryption over FDC3 channels.
EncryptedBroadcastSupport: Encrypts outgoing context with a symmetric key and broadcasts it asfdc3.security.encryptedContext. Also sets up a listener for incomingfdc3.security.symmetricKeyRequestmessages to deliver the wrapped key to authorized requestors.EncryptedContextListenerSupport: Listens forfdc3.security.encryptedContextbroadcasts, negotiates the symmetric key with the broadcaster viafdc3.security.symmetricKeyRequest/fdc3.security.symmetricKeyResponse, and decrypts the payload. The handler receives aContextVerificationMetadatathird argument (as aSecurityAwareContextHandler) withencryption: 'decrypted'on success.
High-level abstractions for managing metadata alongside FDC3 contexts.
MetadataHandler: Manages packing and unpacking of app-provided metadata (signature,antiReplay,traceId) into and out of FDC3 contexts. Supports both FDC3 3.0+ (where metadata is a first-classbroadcastparameter) and earlier versions (where it is embedded in the context object under__appMeta).
Provides a secure bridge — typically over WebSockets — allowing a frontend application to delegate sensitive cryptographic operations to a trusted backend without exposing private keys in the browser.
FDC3Handlers: The interface your trusted backend implements. Defines three methods:handleRemoteChannel(mirror a channel to the backend for signing/encrypting broadcasts),remoteIntentHandler(register an intent handler that runs on the backend), andexchangeData(a general-purpose RPC for operations such as signing a context or unwrapping a symmetric key).BackendIntentHandler: The handler type returned byremoteIntentHandler. Like the standard FDC3IntentHandlerbut with the return type widened to includePrivateChannelSignal, so backend implementations can signal the frontend to create aPrivateChannelwithout unsafe casts.PrivateChannelSignal/PRIVATE_CHANNEL_SIGNAL: A sentinel type and constant ({ type: 'private' }) that aBackendIntentHandlerreturns to signal the frontend to callcreatePrivateChannel()and export it to the backend viahandleRemoteChannel. This is a secure-boundary-internal protocol token — it is never transmitted over FDC3 or seen by the Desktop Agent.DefaultFDC3Handlers: A base class implementingFDC3Handlerswith no-op defaults, intended to be subclassed.ClientSideHandlersImpl/connectRemoteHandlers: Client-side stub that implementsFDC3Handlersby forwarding calls to the backend over a WebSocket.ServerSideHandlersImpl/setupWebsocketServer: Server-side adapter that receives WebSocket messages and dispatches them to yourFDC3Handlersimplementation.
To explore the capabilities of the library and see these components in action, refer to the examples in the samples directory.
The samples directory contains a dedicated README with sequence diagrams illustrating how the different components interact across the secure boundary.
- Signed Broadcasts: Authenticate the sender of a context message.
- Encrypted Channels: Protect message privacy from the Desktop Agent and other observers. Two patterns are provided: backend key (stricter data boundary, decrypted plaintext never in browser) and frontend key (lower latency, symmetric key returned to browser after one-time unwrap on backend).
- Mutual Intent Authentication: Verify both the raiser and the responder of an FDC3 intent.
- User Identity: Securely request and verify identity tokens from an identity provider app via the
GetUserintent.
# Install dependencies
npm install
# Build the project
npm run build
# Run unit and integration tests
npm run test