-
-
Notifications
You must be signed in to change notification settings - Fork 2
license verification
ɳSelf is offline-first. License verification works on disconnected, intermittent, or air-gapped networks. The CLI caches a signed license artifact and validates it locally on every command.
The CLI prefers availability over strict revocation. Two independent clocks govern behavior, and they are easy to confuse:
-
Cache age — how long since the CLI last reached
ping.nself.org. This is the offline ladder below. - License expiry — the server-reported end of the subscription. See Post-Expiry Grace.
Thresholds are GraceSoftThreshold and GraceHardThreshold in internal/license/grace.go.
| Cache age | State | Behavior | User signal |
|---|---|---|---|
| Under 72 hours | valid |
Fail-open, silent | None |
| 72 hours to 7 days | grace_soft |
Fail-open, full access, warning |
License validation is N old. Connect to the internet to refresh. plus the remaining window |
| Over 7 days | grace_hard |
Read-only — commands still run, writes are refused | License validation expired (N offline). Paid plugins are in read-only mode. |
| Bad signature, any age | — | Fail-closed, always | Signature verification failure |
Two properties of this table are load-bearing and are the ones most often misremembered:
72 hours, not 7 days, is when the warning starts. The silent window is deliberately sized to cover a Friday-evening-to-Monday-morning outage on our side with margin, so a blip on the license server never alarms a paying customer mid-weekend.
Past 7 days the CLI degrades to read-only — it does not refuse to run. CanProceed stays true and only WriteAllowed flips to false. You keep your stack readable and inspectable while offline; you cannot mutate it until you refresh.
Plugin installs are stricter than ordinary commands. bundleEntitledFromGrace requires WriteAllowed, so once the cache passes 7 days a bundle install is refused outright rather than degraded — installing is a write. This is why the offline licensing page describes the ceiling as failing closed while this page describes it as read-only: same threshold, two different call paths. A revoked license is refused at any cache age on both paths.
The 7-day ceiling does not widen alongside the soft threshold. Validation sends only the license key over the wire, with no per-machine identifier, so a local cache is a bare copyable credential. Every extra day of ceiling multiplies that exposure, and 7 days is the accepted tradeoff between outage tolerance and copied-cache abuse.
A bad signature is never accepted. Cache age cannot bypass cryptographic verification — the cache carries an Ed25519 signature that is checked locally on every command.
Separately from the offline ladder, a license whose server-reported expiry has passed keeps working for 30 days (PostExpiryGraceWindow), with a warning, before paid plugins go dormant. Reaching this state means the subscription lapsed, not that the network is down; refreshing the cache will not clear it.
| Variable | Default | Purpose |
|---|---|---|
LICENSE_CACHE_PATH |
~/.cache/nself/license.json |
Cache file location. Override for shared CI runners or air-gapped hosts. |
NSELF_LICENSE_FAIL_OPEN |
unset |
=1 replaces the bounded ladder with an unbounded cache check on the network-unreachable branch (checker.go:84-87). CI and air-gap only. |
The 72h and 7d thresholds themselves are compile-time constants, not configuration — nothing tunes them to a different number. NSELF_LICENSE_FAIL_OPEN=1 does not move them either; it takes a different branch entirely (bundleEntitledFromCache, tier check with no time window at all), which is why it must never be set on a production install. It does not disable revocation or override a server that answers 401/403.
nself license refreshPulls a fresh signed artifact from ping.nself.org/license/validate for every configured key, replaces the cache, and resets the age clock. Run after extended offline periods, after key rotation, or when the warning fires.
For hosts that never reach the public internet, move a signed cache across the air gap with export / import. Run the export on a machine that can reach ping.nself.org and holds the same license key:
# On the connected machine
nself license refresh
nself license export > license-cache.json
# Transfer the file, then on the air-gapped host
nself license import license-cache.jsonThe imported entry keeps its Ed25519 signature and is verified locally, so an air-gapped host gets the same guarantees as a connected one. The transferred cache ages on the same ladder above, so repeat the transfer before the 7-day ceiling to stay out of read-only mode.
NSELF_LICENSE_SKIP_VERIFY=1 exists for importing an unsigned entry and requires --force to be acknowledged explicitly. It bypasses signature verification — do not use it outside local testing.
simulate-offline backdates the cache so you can exercise each band without waiting. It requires LICENSE_ALLOW_SIMULATION=true and is disabled by default:
LICENSE_ALLOW_SIMULATION=true nself license simulate-offline 1 # silent
LICENSE_ALLOW_SIMULATION=true nself license simulate-offline 5 # warning
LICENSE_ALLOW_SIMULATION=true nself license simulate-offline 10 # read-only
nself license simulate-offline --clear # resetCache corruption. Delete ~/.cache/nself/license.json and run nself license refresh. The cache is regenerable.
Signature invalid after CLI upgrade. Run nself license refresh. Major version bumps may rotate signing keys.
Manual signature verification. There is no separate verify subcommand — every command validates the cached signature locally before it runs. To inspect the cache contents without triggering a network call, print it directly:
nself license show --jsonStuck in read-only. The cache is more than 7 days old. Connect to the internet and run nself license refresh. If the network is restricted, use the air-gap export / import flow above.
ɳSelf CLI v1.0.9. MIT licensed. Docs CC BY 4.0.
GitHub · Issues · Discussions · nself.org · nself.org/docs
Getting Started
Commands
- Commands, Overview
- Lifecycle: cmd-init · cmd-build · cmd-start · cmd-stop · cmd-restart · cmd-dev
- Monitoring: cmd-status · cmd-logs · cmd-health · cmd-urls · cmd-doctor · cmd-monitor · cmd-alerts · cmd-sentry · cmd-watchdog
- Data: cmd-db · cmd-backup · cmd-dr · cmd-queue · cmd-webhooks
- Config: cmd-config · cmd-service · cmd-env · cmd-promote
- Networking: cmd-ssl · cmd-trust · cmd-dns-setup
- Security: cmd-access · cmd-security · cmd-secrets
- Tenancy: cmd-tenant · cmd-billing
- Plugins: cmd-plugin · cmd-license · cmd-dogfood (extracted, CLI-R11) · cmd-k8s (extracted, CLI-R11) · cmd-encryption (extracted, CLI-R11) · cmd-waf (extracted, CLI-R11) · cmd-federation (extracted, CLI-R11) · cmd-mail (extracted, CLI-R11) · cmd-dlq (extracted, CLI-R11)
- AI: cmd-ai · cmd-claw · cmd-model
- Templates: cmd-template
- Utilities: cmd-exec · cmd-clean · cmd-reset · cmd-update · cmd-upgrade · cmd-version · cmd-admin · cmd-migrate · cmd-migrate-firebase · cmd-migrate-supabase · cmd-completion
Features
- Features, Overview
- Feature-Auth
- Feature-Storage
- Feature-Search
- Feature-Functions
- Feature-Email
- Feature-Monitoring
- Feature-Plugins
- Feature-nClaw, AI Assistant
- Feature-nChat, Messaging
- Feature-nTV, Media Player
- Feature-nFamily, Family Social
- Feature-nCloud, Managed Hosting
- Feature-Memory-Rooms, Knowledge Organization
- Feature-Agent-Dashboard, Agent Metrics
- Feature-Image-Generation, AI Image Generation
Configuration
- Configuration, Overview
- Config-Env-Vars
- Config-Postgres
- Config-Hasura
- Config-Auth
- Config-Nginx
- Config-Optional-Services
- Config-Custom-Services
- Config-System
Plugins (87 + 10 monitoring)
Free (25)
- plugin-backup
- plugin-content-acquisition
- plugin-content-progress
- plugin-cron
- plugin-donorbox
- plugin-feature-flags
- plugin-github
- plugin-github-runner
- plugin-invitations
- plugin-jobs
- plugin-link-preview
- plugin-mdns
- plugin-mlflow
- plugin-monitoring
- plugin-notifications
- plugin-notify
- plugin-paypal
- plugin-search
- plugin-shopify
- plugin-stripe
- plugin-subtitle-manager
- plugin-tokens
- plugin-torrent-manager
- plugin-vpn
- plugin-webhooks
Pro (62)
- plugin-access-controls
- plugin-activity-feed
- plugin-admin-api
- plugin-nself-ai-gateway
- plugin-nself-ai-mcp
- plugin-nself-ai-mcp
- plugin-analytics
- plugin-auth
- plugin-backup-pro
- plugin-bots
- plugin-browser
- plugin-calendar
- plugin-cdn
- plugin-chat
- plugin-claw
- plugin-claw-budget
- plugin-claw-news
- plugin-claw-web
- plugin-cloudflare
- plugin-cms
- plugin-compliance
- plugin-cron-pro
- plugin-ddns
- plugin-devices
- plugin-documents
- plugin-donorbox-pro
- plugin-entitlements
- plugin-epg
- plugin-file-processing
- plugin-game-metadata
- plugin-geocoding
- plugin-geolocation
- plugin-google
- plugin-home
- plugin-idme
- plugin-knowledge-base
- plugin-linkedin
- plugin-livekit
- plugin-media-processing
- plugin-meetings
- plugin-moderation
- plugin-mux
- plugin-notify-pro
- plugin-object-storage
- plugin-observability
- plugin-paypal-pro
- plugin-photos
- plugin-podcast
- plugin-post
- plugin-realtime
- plugin-recording
- plugin-retro-gaming
- plugin-rom-discovery
- plugin-shopify-pro
- plugin-social
- plugin-sports
- plugin-stream-gateway
- plugin-streaming
- plugin-stripe-pro
- plugin-support
- plugin-tmdb
- plugin-voice
- plugin-web3
- plugin-workflows
Planned (26)
plugin-auditplugin-blogplugin-checkoutplugin-commerceplugin-drmplugin-exportplugin-flowplugin-importplugin-ldapplugin-mailgunplugin-mediaplugin-oauth-providersplugin-pagesplugin-postmarkplugin-rate-limitplugin-reportsplugin-samlplugin-schedulerplugin-sendgridplugin-ssoplugin-subscriptionplugin-thumbplugin-transcoderplugin-twilioplugin-wafplugin-watermark
Guides
- Guide-Production-Deployment
- Guide-SSL-Setup
- Guide-Multi-Tenancy
- Guide-Security-Hardening
- Guide-Monitoring-Setup
- Guide-Backup-Restore
- Guide-Custom-Services
- Guide-Migration-from-v1
Architecture
Reference
- API-Reference
- error-codes, Error Codes
Licensing
Security
Brand
Operations
- operations/release-cascade, Release Cascade
- operations/self-healing, Self-Healing Schema
- operations/redis-tuning, Redis Pool Tuning
- operations/meilisearch-warmup, MeiliSearch Warm-Up
- operations/jwt-rotation, JWT Key Rotation
- operations/windows-wsl2-setup, Windows / WSL2 Setup
- operations/gemini-oauth-reauth, Gemini OAuth Reauth
Contributing
Admin
- USER-ACTION-QUEUE, Pending Admin Actions
All commands (52)
- A: cmd-access · cmd-account · cmd-admin
- B: cmd-backup · cmd-build · cmd-bundle
- C: cmd-ci · cmd-clean · cmd-completion · cmd-config
- D: cmd-db · cmd-deploy · cmd-dev · cmd-doctor
- E: cmd-env · cmd-exec
- F: cmd-functions
- G: cmd-generate
- H: cmd-health · cmd-help-topics
- I: cmd-init · cmd-install
- L: cmd-license · cmd-login · cmd-logout · cmd-logs
- M: cmd-man · cmd-mcp · cmd-migrate
- O: cmd-oauth · cmd-ops
- P: cmd-plugin · cmd-promote
- R: cmd-remove · cmd-reset · cmd-restart · cmd-runner
- S: cmd-secrets · cmd-security · cmd-self-heal · cmd-server · cmd-service · cmd-start · cmd-status · cmd-stop
- T: cmd-telemetry · cmd-template · cmd-trust
- U: cmd-update · cmd-urls
- V: cmd-verify-sbom · cmd-version