-
Notifications
You must be signed in to change notification settings - Fork 0
Add cryptographically signed quote expiry validation with dynamic TTL support #102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Co-authored-by: rkeene <5068442+rkeene@users.noreply.github.com>
…e tests Co-authored-by: rkeene <5068442+rkeene@users.noreply.github.com>
Co-authored-by: rkeene <5068442+rkeene@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Co-authored-by: rkeene <5068442+rkeene@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Co-authored-by: rkeene <5068442+rkeene@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Co-authored-by: rkeene <5068442+rkeene@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Co-authored-by: rkeene <5068442+rkeene@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
src/services/fx/server.ts
Outdated
| this.fx = config.fx; | ||
|
|
||
| /* Validate and set quoteTTL with default and maximum */ | ||
| const maxQuoteTTL = 5 * 60 * 1000; // 5 minutes (message expiry) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot This value is repeated, it should be lifted into the module scope so we don't need to repeat it -- even better might be to have a module scoped function which takes a value and determines if it's an acceptable quoteTTL since that is repeated as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored in commit bedaf40. Created module-scoped constants MAX_QUOTE_TTL and DEFAULT_QUOTE_TTL (both set to 5 * 60 * 1000) and a validateQuoteTTL() function. This eliminates the duplication of both the value and the validation logic between the constructor and the getQuote route handler.
Co-authored-by: rkeene <5068442+rkeene@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Add Cryptographically Signed Quote Expiry Information
This PR adds optional expiry information to FX quotes to make it easier for clients to understand quote lifetime. The expiry information is cryptographically signed to prevent tampering.
Changes Made:
Type changes (
common.ts):expiryobject containingserverTimeandexpiresAt(both required when present)Configuration (
server.ts):quoteTTL?: number | ((request: ConversionInputCanonicalJSON) => number | Promise<number>)toKeetaAnchorFXServerConfig.fxServer-side changes (
server.ts):quoteTTLcan be a function for request-based TTL determinationMAX_QUOTE_TTL,DEFAULT_QUOTE_TTLconstants andvalidateQuoteTTL()function to avoid duplicationcreateExchangeendpoint validatesexpiry.expiresAtbefore processing quoteQuoteValidationFailederrorvalidateQuotecallbackTests (
server.test.ts):quoteTTLwith captured variable for simplified testingKey Features:
✅ Cryptographically signed expiry - Expiry timestamps are included in the quote signature, preventing tampering
✅ Dynamic TTL support -
quoteTTLcan be a function for context-aware TTL determination based on request properties✅ Default TTL matching message expiry - Defaults to same timeout as message validation
✅ Validation - Server throws error if quoteTTL exceeds maximum (applies to both static and function-returned values)
✅ Structured expiry data - Optional
expiryobject with required fields when present✅ Millisecond precision - ISO 8601 format with full timestamp precision
✅ Simplified testing - Function-based quoteTTL allows reusing server with different TTL values
✅ DRY principle - Module-scoped constants and validation function eliminate code duplication
✅ All tests passing - 50 tests pass, linting clean
Usage Examples:
Static TTL:
Dynamic TTL:
When
quoteTTLis configured, quotes include:{ "expiry": { "serverTime": "2025-11-10T18:00:00.123Z", "expiresAt": "2025-11-10T18:00:30.123Z" }, "signed": { "signature": "..." // Signature includes expiry data } }Note: The expiry information is cryptographically signed, so any attempt to modify the expiry timestamps will cause signature verification to fail.
Fixes #99
Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.