station-v0.23 · Local DRM + Salesforce module (Phase 2 goes real)
What's new
Local DRM — sellable modules (the Phase 2 unlock)
module_entitlement.pyprimitive — signed per-module licenses, verified OFFLINE against a pinned issuer key. Twin ofentitlement.py(org-tier) but scoped to one module — blast-radius separation between key compromises.- Loader gate — modules with
license_required: truein their manifest refuse to register commands unless a valid, install-bound, unexpired-or-in-grace license file exists underWS/module_licenses/<safe_id>.json. - 7-day grace past expiry — warns but never blocks. Enterprise ops teams must never be gated by billing lag.
- Install binding — every license carries this install's Ed25519 pubkey inside the signed body. Copy a license to a second machine → refused. Nothing to unlock on the box; the lock IS the machine identity.
railcall licenseCLI —activate <path>/list/verify [module_id]/deactivate <module_id>. Delegates to the station primitive (the ONE audited verify path).- Modules tab license badge — tier + days-left when licensed, GRACE warning in the 7-day window past expiry.
First real paid module: railcall/salesforce ($199/mo)
- Installable from marketplace:
railcall market install sami666/salesforce - 13 airlock commands covering the full lead-to-cash surface:
- Leads:
sf.lead.create,sf.lead.update,sf.lead.convert - Contacts:
sf.contact.create,sf.contact.update - Accounts:
sf.account.create,sf.account.update - Opportunities:
sf.opportunity.create,sf.opportunity.update_stage,sf.opportunity.close - Cases:
sf.case.create,sf.case.update,sf.case.close
- Leads:
- OAuth 2.0 refresh-token flow — bring your own Connected App; token never appears in receipts. Sandbox orgs supported via
test.salesforce.comtoken_url. - 14-day free trial available on request.
Also in this cut
- New loader helpers:
_oauth_refresh(provider),_http_get/patch/delete_json— unlocks Salesforce, HubSpot OAuth, Google, Microsoft, and any REST API ongrant_type=refresh_token. _vault_save(provider, value)for helpers that need to persist derived state (e.g. OAuth cached access_token) without going through the credential-save airlock.
SHA256
5089c33f7f051d9390ffaa699cac1d01656aece9ffee36a8cf36e811e5e2f68d
Install
curl -fsSL https://railcall.ai/install.sh | bash
Existing installs
railcall update