Skip to content

Disk Cache & Offline Fallback #66

@fupelaqu

Description

@fupelaqu

Epic 5: Licensing Infrastructure

User Story

As a server operator,
I want the fetched JWT to be cached to disk,
So that the server can start with valid licensing even when the license backend is temporarily unreachable.

Acceptance Criteria

Given a successful JWT fetch via API key
When the JWT is validated
Then it is written to ~/.softclient4es/license-cache.jwt (configurable via cache-dir)

Given no valid static JWT and API key fetch fails (network error)
When a cached JWT exists on disk at ~/.softclient4es/license-cache.jwt
Then the cached JWT is loaded, validated (signature + expiry), and used
And a WARNING is logged: "Using cached license (API key fetch failed)"

Given a cached JWT that is valid but expired within the grace period
When it is loaded as a fallback
Then it is used with a WARNING: "Using cached license (expired, within grace period)"

Given a cached JWT that is expired beyond the grace period or has an invalid signature
When it is loaded as a fallback
Then it is rejected
And the system degrades to Community tier (Step 4)

Given the server is running in static JWT mode (no API key configured)
When a static JWT is successfully validated
Then no disk cache is written — the configured JWT is the source of truth

Given the cache directory ~/.softclient4es does not exist
When a JWT needs to be cached
Then the directory is created with appropriate permissions (owner-only read/write)

Given the cache file cannot be written (permissions, disk full)
When a cache write fails
Then a WARNING is logged but the server continues normally with the in-memory JWT

Dependencies

  • API Key Client & JWT Fetch (FR25)

Requirements

  • FR26: Disk cache for JWT persistence across restarts (API key mode network failure fallback)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions