Why shinten, and why now?
Breaches take what is stored
Years of order records, old enquiries, tables left behind by a forgotten plugin, backups. Most breaches are not wiretaps; they are stored data walking out. Store it sealed, and what walks out is ciphertext.
Small shops carry the heaviest burden
E-commerce plugins, an outsourced warehouse, SaaS accounts. Every place an address passes through is another place to protect. Pass it through unreadable, and the only place to protect is the device that opens it.
Keys stay with the people who do the work
No vault, no key service. The shipping desk’s computer, the answering person’s phone. The key lives there, and the site publishes only the public half. The opening itself can be left to that person’s AI agent.
How it works, in three minutes
Take an online shop where a customer places an order.
The customer fills in the form
The moment they press submit, the browser seals the name, address and phone number to the shipping desk’s public key. Only the postal code is sent in the clear, for the shipping fee. Nothing changes for the customer: no sign-up, no app.
The site only holds the envelope
The server and the database receive the postal code and an envelope, the ciphertext. Order management, backups, integrations: wherever it goes, it cannot be read. Nothing is installed on the server; it stores what arrives.
It opens at the shipping desk
Only the device of the person who prints labels has the private key. shinten-ship opens the envelopes there and writes the import file for Yamato B2 Cloud or Japan Post’s label software. Once the labels are printed the import file is purged, and the address is sealed again.
If the site is taken over, a replaced key shows
The site serves the list of public keys its forms encrypt to. Whoever takes over the site will try to add a key of their own to that list, or swap one, so that they can decrypt what is typed from then on. Instead of trusting the site, shinten makes sure this shows.
Every ciphertext names the keys used
The ciphertext records, where it cannot be altered, the fingerprints (thumbprints) of the public keys it was actually encrypted to. A key’s name can be copied; its fingerprint cannot.
Nothing is decrypted for keys not approved
The shipping desk keeps the list of public keys it approved. If even one order was encrypted to another key, or is missing an approved one, shinten-ship stops and makes no labels at all. A fake key served to only some customers is caught at their order.
Watched from outside the site
shinten watch checks the key list the site serves against the approved keys on a schedule, and says when they differ, before any order arrives.
A page modified at the moment of input can read what is typed without touching any key, and this does not stop it. That takes an input field served from somewhere the site does not control: an iframe on another domain.
What the site keeps, and what it does not
Not kept
- Name, address, phone number (shipping profile)
- Message, reply address, name (inquiry profile)
- Private keys (never on the site)
Kept
- The postal code (for fees and delivery zones) or the enquiry category (for routing)
- The envelope, a JWE document only the addressees’ keys can open
- The list of recipients’ public keys, one JSON file
If the whole database leaks, what comes out is postal codes and ciphertext.
Compared with transport and disk encryption
| A typical site (HTTPS and disk encryption) | shinten | |
|---|---|---|
| What is protected | Data in transit, and a stolen disk | Data at rest, anywhere on the server side |
| Can the server read it | Yes (decrypted while running) | No |
| Database dumps and backups | Not protected | Protected: still ciphertext |
| Where it opens | On the server | Only on the device that holds the key |
| If the site is taken over | Stored data is read too | Stored ciphertext stays unreadable; a replaced public key is caught at the first order |
| What it takes | Certificates and server configuration | Two attributes on the form and a published key set. No server change |
| Cost structure | Maintenance and audits | Free software (Apache-2.0). Integration in-house, or with help |
What you need
By role: what each one holds and runs. Nothing new runs on the server.
The site operator (a shop, a help desk)
- Add two attributes to the form (the profile and where the key set is) and load one script
- Store the envelope as it arrives, next to the clear fields (the postal code). An envelope opens only beside the clear fields it was sealed with
- Publish the key set (one JSON file) on the site; add a line when a desk or a backup key is added
Whoever opens (the shipping desk, the person who answers)
- Generate a key on their own device and hand only the public half to the site operator
- For shipping, shinten-ship turns the order export into the carrier’s import file and purges it after printing. For enquiries, the shinten CLI or an AI agent opens them
- Always keep a backup key. An envelope sealed to a lost key alone cannot be opened by anyone
The customer
- Fills in the form as always. No sign-up, no app
- Needs a browser with JavaScript
- Nothing is left on their device
What this version does
Now
- The shipping and inquiry profiles; a browser script, a library, a CLI and an MCP server
- shinten-ship: import files for Yamato B2 Cloud (基本レイアウト) and Japan Post ゆうパックプリント R, with purge and a record after printing
- Sealing to several recipients (desks and backup keys); detection of swapped clear fields
- Detection of a replaced public key (approved keys, shinten watch)
Next
- Drop-in parts for Shopify, WooCommerce, Salesforce and other existing systems
- Input fields served from outside the site (an iframe)
- More carriers (Sagawa and others)
- A deedlog trail of when envelopes were opened and purged, and of key changes
For developers
- Install
- On the site, one
<script src="…/shinten.browser.js">ornpm install shinten. At the desk,npm install -g shinten-ship. Node.js 20 or later. - The envelope
- JWE in JSON serialization: ECDH-ES+A256KW to P-256 JWKs, one recipient per key. The clear fields are bound to the envelope as AAD; a swapped postal code refuses to open.
- Keys used
- The protected header records the RFC 7638 thumbprints of the keys encrypted to.
open(sealed, key, { recipients })refuses, withRecipientError, a ciphertext not encrypted to exactly the approved keys. - Profiles
- shipping keeps postalCode in the clear and requires name and address; inquiry keeps category in the clear and requires message. A field a profile does not know is always sealed; a sealed field with the name of a clear one is refused.
- Opening
- The CLI is
shinten keygen -o / seal / open -r / inspect / watch. The MCP server opens with the key named bySHINTEN_KEY, checks against the keys inSHINTEN_RECIPIENTS, and writes the plaintext nowhere. - What it does not protect
- A page modified at the moment of input (a server already compromised) can read a field before it is sealed. SRI and a CSP narrow that window; closing it takes input fields served from outside the site. A lost key loses every envelope sealed to it alone.
- Licence
- Apache-2.0. shinten and shinten-ship on GitHub, and on npm.
- Related
- kangoh, shared reward vouchers without a customer database. A sister project built on the same “hold nothing” idea.
Talk to us
Ask us about adding shinten to a shop or a help desk, connecting it to shipping operations and warehouses, and designing key custody. The software is free. What costs is help with design and integration.
What you send is used only to answer you and is not stored on this site. See the privacy policy.
