Human Sky Capsule Format v1 =========================== Status: Published Human Sky Capsule Format v1 Media type: application/json; charset=utf-8 Recommended extension: .hsky Container discriminator: "format": "human-sky-capsule" Purpose ------- A Human Sky capsule is a portable encrypted copy of a "star in time". The file contains ciphertext and the complete public parameters required to derive its decryption key from My Sky Key. It does NOT contain the My Sky Key secret. A .hsky extension is also used by other Human Sky JSON containers. Readers MUST dispatch by the top-level "format" field. Existing key files use "human-sky-key". Capsule files use "human-sky-capsule". Required top-level fields ------------------------- format literal "human-sky-capsule" version integer 1 capsule_id Human Sky capsule identifier created_at RFC 3339 / ISO-8601 UTC timestamp unlock_at RFC 3339 / ISO-8601 UTC timestamp mode literal "future" sky_id public Sky ID associated with My Sky Key key_source literal "derived_from_sky_key" key_derivation object described below encryption object described below ciphertext base64url without padding integrity object described below Key derivation -------------- algorithm HKDF-SHA-256 salt 16 random bytes, base64url without padding info UTF-8 string "humansky/capsule/v1|" + capsule_id output_bits 256 The HKDF input keying material (IKM) is the UTF-8 encoding of the exact string: human-sky-capsule-root-v1|| where and are the values stored in My Sky Key identity. No password stretching is required because the secret is generated with a cryptographically secure random number generator and has high entropy. Encryption ---------- algorithm AES-256-GCM nonce 12 random bytes, base64url without padding tag_bits 128 aad UTF-8 string plaintext_encoding UTF-8 compression none The authenticated additional data (AAD) is exactly: humansky/capsule/v1|| MUST use canonical JavaScript Date.toISOString() form with exactly three fractional-second digits and a trailing Z, for example: 2031-05-17T00:00:00.000Z The AES-GCM authentication tag is appended to the ciphertext by WebCrypto and is therefore included in the top-level "ciphertext" byte string. Integrity / archival check -------------------------- algorithm SHA-256 scope literal "ciphertext bytes" digest SHA-256 of the decoded ciphertext bytes, base64url without padding AES-GCM already authenticates the encrypted message. The separate SHA-256 is an archival corruption check so software can distinguish a damaged file from a wrong key before attempting decryption. It is not an independent authenticity signature. Opening a capsule ----------------- 1. Parse the JSON and require format="human-sky-capsule", version=1. 2. Obtain My Sky Key identity (sky_id + secret). 3. Require the identity sky_id to match the capsule sky_id. 4. Base64url-decode salt, nonce and ciphertext. 5. Verify SHA-256(ciphertext bytes) against integrity.digest. 6. Rebuild IKM and derive a 256-bit AES-GCM key with HKDF-SHA-256. 7. Decrypt ciphertext with the stored nonce, 128-bit tag and exact AAD. 8. Decode plaintext as UTF-8. The portable file is owner-controlled. Human Sky's normal online experience keeps the star closed until unlock_at; the portable file itself contains the encrypted payload required for independent local opening when combined with My Sky Key. My Sky Key recovery code ------------------------ The standalone Human Sky opener may also accept an HSK1 recovery code. The code encodes the same sky_id and secret as a human-sky-key .hsky file. Software must validate the checksum before using it. Compatibility rule ------------------ A reader MUST reject unknown format versions or crypto algorithms rather than silently guessing. Future formats must use a new version number and publish a new specification.