Secure storage and distribution of cryptographic keys in ATProto applications
1import { LRUCache } from 'lru-cache'
2
3/**
4 * Cache entry for group keys
5 */
6export interface GroupKeyCacheEntry {
7 secretKey: string
8 version: number
9 isActive: boolean // Active keys use shorter TTL, historical use longer
10}
11
12export const DEFAULT_KEY_CACHE_MAX_SIZE = 1000
13export const DEFAULT_ACTIVE_TTL = 60 * 60 * 1000 // 1 hour
14export const DEFAULT_HISTORICAL_TTL = 24 * 60 * 60 * 1000 // 24 hours
15
16/**
17 * Create a cache for group keys with TTL support
18 */
19export function createKeyCache(
20 maxSize: number,
21): LRUCache<string, GroupKeyCacheEntry> {
22 // This will have a custom TTL based on whether key is active or historical
23 return new LRUCache<string, GroupKeyCacheEntry>({
24 max: maxSize,
25 ttlAutopurge: true,
26 ttlResolution: 1000, // Check expiry every second
27 updateAgeOnGet: false, // Don't refresh TTL on access (cache invalidation, not LRU)
28 updateAgeOnHas: false,
29 })
30}
31
32/**
33 * Service auth token cache entry
34 */
35export interface ServiceAuthTokenEntry {
36 token: string
37 expiresAt: number // Unix timestamp in milliseconds
38}
39
40const DEFAULT_TOKEN_TTL = 60 * 1000 // 60 seconds
41
42/**
43 * Create a cache for service auth tokens with 60s TTL
44 */
45export function createTokenCache(): LRUCache<string, ServiceAuthTokenEntry> {
46 return new LRUCache<string, ServiceAuthTokenEntry>({
47 max: 100,
48 ttl: DEFAULT_TOKEN_TTL,
49 ttlAutopurge: true,
50 ttlResolution: 1000,
51 updateAgeOnGet: false,
52 updateAgeOnHas: false,
53 })
54}
55
56/**
57 * Generate cache key for group key
58 */
59export function getGroupKeyCacheKey(groupId: string, version?: number): string {
60 return version ? `${groupId}:${version}` : `${groupId}:latest`
61}
62
63/**
64 * Generate cache key for service auth token
65 */
66export function getServiceAuthCacheKey(aud: string, lxm: string): string {
67 return `${aud}:${lxm}`
68}