fix: propagate first_seen_at into lease and hop route signing (extreme minimal)
Lee Yunjin committed
Apr 30, 2026 at 11:16 UTC
be6d4a3dc829c9a2933a5850d66fa69c79d70f76
3 files changed
+5
portal/lease.go
+1
@@ -443,6 +443,7 @@ func (r *leaseRegistry) RegisterHopRoute(route *types.HopRoute, now time.Time) (
443
},
444
Hostname: matchHostname,
445
Metadata: route.Metadata.Copy(),
446
+ FirstSeenAt: route.FirstSeenAt.UTC(),
447
ExpiresAt: expiresAt,
448
hopToken: matchToken,
449
hopNextOverlayIPv4: overlayIPv4,
sdk/api_client.go
+1
@@ -233,6 +233,7 @@ func (l *listener) syncHopRoutes(ctx context.Context, method string, expiresAt t
233
234
var syncErr error
235
for _, unsignedRoute := range orderedRoutes {
236
+ unsignedRoute.FirstSeenAt = expiresAt.Add(-30 * time.Second)
237
route, err := auth.SignHopRoute(method, unsignedRoute, l.identity, expiresAt)
238
if err != nil {
239
if method == http.MethodDelete {
types/api.go
+3
@@ -130,6 +130,7 @@ type HopRoute struct {
130
Metadata LeaseMetadata `json:"metadata,omitempty"`
131
ForwardRelay RelayDescriptor `json:"forward_relay"`
132
ForwardToken string `json:"forward_token"`
133
+ FirstSeenAt time.Time `json:"first_seen_at,omitempty"`
134
ExpiresAt time.Time `json:"expires_at,omitempty"`
135
Signature string `json:"signature,omitempty"`
136
}
@@ -148,6 +149,7 @@ func HopRouteBytes(method string, route HopRoute) ([]byte, error) {
149
MatchToken string `json:"match_token"`
150
ForwardRelay json.RawMessage `json:"forward_relay"`
151
ForwardToken string `json:"forward_token"`
152
+ FirstSeenAtUnixNano int64 `json:"first_seen_at_unix_nano"`
153
ExpiresAtUnixNano int64 `json:"expires_at_unix_nano"`
154
}{
155
Purpose: "portal hop route v1",
@@ -158,6 +160,7 @@ func HopRouteBytes(method string, route HopRoute) ([]byte, error) {
160
MatchToken: strings.TrimSpace(route.MatchToken),
161
ForwardRelay: json.RawMessage(forwardRelay),
162
ForwardToken: strings.TrimSpace(route.ForwardToken),
163
+ FirstSeenAtUnixNano: route.FirstSeenAt.UTC().UnixNano(),
164
ExpiresAtUnixNano: route.ExpiresAt.UTC().UnixNano(),
165
}
166
return json.Marshal(payload)