Security

What GuardKin can read, and what it cannot.

The app sealed one real record, then tried to read it as each party that touches it. Below are the results, the keys behind them, and the list of what is not true yet.

One record, four readers

The same policy reads four ways.

The app sealed one life insurance policy, then tried to read it as each party that touches it. These are the results, from the app’s own code.

More to the side. Swipe, scroll sideways, or use the arrow keys.

  1. The owner

    Opens all of it.

    The record was sealed on the owner’s device, so that is where it opens. It takes the Master Password and the Secret Key together. The owner’s recovery cards are the other way to the same key: any 3 of the 5 rebuild it.

    3of 3

    layers open

    On the owner’s deviceBoth secrets entered

    Family term life — Example Mutual

    Carrier
    Example Mutual
    Policy number
    DEMO-POL-2040
    Beneficiary
    Marcus Chen
    Cover
    $500,000

    The three sealed layers

    • ContentOpened519 bytes, sealed under the content key
    • OutlineOpened123 bytes, sealed under the metadata key
    • FigureOpened144 bytes, sealed under the figure key
  2. GuardKin’s database

    Holds sealed bytes and a few plain labels.

    This is the row GuardKin stores. The three sealed layers are bytes it holds no key for. The plain columns are what the service needs to find and sort a record, so GuardKin does know this is a term life policy.

    A stolen database, a leaked backup or a court order for our servers yields your records only as locked bytes, and nothing GuardKin holds unlocks them. The keys are yours, and three of your five recovery cards rebuild them.

    0of 3

    layers the database can open

    vault_itemsOne row, as stored
    • id0198a7c2-3b5e-7d41-9a0f-5c1e2b7d9a10Plain
    • item_typeinsurancePlain
    • item_subtypeterm_lifePlain
    • classificationconfidentialPlain
    • content_ciphertext\x0fc8897a14e66873d4b8f2a3… (519 bytes)Sealed
    • metadata_ciphertext\x60cd552c6b2d4d195dfdb2df… (123 bytes)Sealed
    • metadata_mrk_version1Plain
    • amount_ciphertext\x05a355ccb716c9be6e34cc88… (144 bytes)Sealed
    • amount_key_domain2Plain

    6 more columns of this row are not drawn.

  3. An advisor

    Reads the outline, not the policy.

    With the owner’s consent, the advisor holds a copy of the metadata key, wrapped to the advisor’s own key. It opens the outline: the type, the title and the dates.

    The content key and the figure key come from a root the advisor never holds. If the owner shares the figure, the advisor receives a key for that figure alone.

    1of 3

    layer the advisor can open

    With the metadata key onlyConsent in place
    Type
    insurance
    Title
    Family term life — Example Mutual
    Updated
    October 22, 2026

    The three sealed layers

    • ContentSealed519 bytes, sealed under the content keyOperationError: The operation failed for an operation-specific reason
    • OutlineOpened123 bytes, sealed under the metadata key
    • FigureSealed144 bytes, sealed under the figure keyOperationError: The operation failed for an operation-specific reason

    The errors are what the app’s own decrypt call threw with this key.

  4. GuardKin staff

    Reads state, not records.

    The operator console counts and sorts: how many records, of what type, last changed when. It selects named columns and has no function that decrypts.

    A database role that was never granted a sealed column backs 3 of 18 operator routes today. Behind it, a read of a denied column is refused by the database itself.

    0of 3

    layers the operator can open

    The operator’s database roleColumns of vault_items
    Can read

    9 of 29

    • id
    • tenant_id
    • item_type
    • classification
    • content_schema_version
    • metadata_mrk_version
    • created_at
    • updated_at
    • deleted_at
    Denied

    12 sealed columns

    • content_ciphertext
    • content_nonce
    • content_associated_data
    • metadata_ciphertext
    • metadata_nonce
    • metadata_associated_data
    • amount_ciphertext
    • amount_nonce
    • amount_associated_data
    • obligation_ciphertext
    • obligation_nonce
    • obligation_associated_data
    Denied

    8 plain columns, not granted

    • item_subtype
    • amount_schema_version
    • amount_key_domain
    • amount_key_version
    • obligation_schema_version
    • value_sign
    • has_amount
    • tier

Sample household. Names and figures come from the app’s own demo vault, not a real client.

Two secrets

The keys come from two secrets the owner holds.

A Master Password and a Secret Key are combined on the owner’s device. GuardKin holds neither, so it cannot reset either one.

256MiB

of memory for every guess at the password, over 3 passes of Argon2id.

Read the derivation, step by step
  1. Master Password

    Chosen by the owner. At least 12 characters. It never leaves the device.

    Owner only
  2. Secret Key

    128 random bits made on the owner’s device and printed in a recovery kit, in the form GUARDKIN1-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XX.

    Owner only
  3. Master Key

    Argon2id over the password, with a salt built from the Secret Key, a server salt and the email address. Made again at every unlock.

    Owner’s device

    Stored nowhere.

  4. Master Root

    32 random bytes made at sign-up. GuardKin stores it only wrapped under the Master Key, as 60 bytes it cannot open.

    Wrapped copy at GuardKin

    Optional recovery cards are shares of it: any 3 of the 5 rebuild it.

  5. Content key and metadata key

    Both come from the Master Root, and each record’s own keys come from them. The content key opens content and figures. The metadata key opens outlines.

    Owner’s device

    The metadata key is also wrapped to each advisor the owner consents to.

The log

A log that shows when it was changed.

Every event is hashed together with the one before it, then signed. Change one, or remove one, and the check fails at that event.

Audit chainAs written · demo key

Nothing changed. Each event links to the one before it, and each hash and signature checks.

  1. 0consent.granted · client00000000…0000 → 56cfb191…5b99Checked
  2. 1vault.item.created · client56cfb191…5b99 → 29163dd6…f056Checked
  3. 2vault.item.listed · advisor29163dd6…f056 → 65e19790…8e49Checked
  4. 3vault.item.updated · client65e19790…8e49 → 1695f959…e084Checked
  5. 4vault.item.listed · advisor1695f959…e084 → 9a80ef5a…594fChecked
  6. 5consent.mrk_rotated · client9a80ef5a…594f → 6fa01b61…e2acChecked

Verified: 6 of 6 events.

Audit chainOne field edited · demo key

After the fact, the actor of event 2 was changed from advisor to client. The stored hash no longer matches the content.

  1. 0consent.granted · client00000000…0000 → 56cfb191…5b99Checked
  2. 1vault.item.created · client56cfb191…5b99 → 29163dd6…f056Checked
  3. 2vault.item.listed · client29163dd6…f056 → 65e19790…8e49Fails here
  4. 3vault.item.updated · client65e19790…8e49 → 1695f959…e084Not reached
  5. 4vault.item.listed · advisor1695f959…e084 → 9a80ef5a…594fNot reached
  6. 5consent.mrk_rotated · client9a80ef5a…594f → 6fa01b61…e2acNot reached

Fails at event 2: event content does not match its recorded eventHash (INTEGRITY)

Audit chainOne event removed · demo key

Event 2 (vault.item.listed) was deleted. The next event still points at it, so the link breaks.

  1. 0consent.granted · client00000000…0000 → 56cfb191…5b99Checked
  2. 1vault.item.created · client56cfb191…5b99 → 29163dd6…f056Checked
  3. 3vault.item.updated · client65e19790…8e49 → 1695f959…e084Fails here
  4. 4vault.item.listed · advisor1695f959…e084 → 9a80ef5a…594fNot reached
  5. 5consent.mrk_rotated · client9a80ef5a…594f → 6fa01b61…e2acNot reached

Fails at event 3: prevHash does not match previous eventHash

Six events written by the app’s audit-log package and checked by its own verifier, under a demo signing key. In production the signing key is held in AWS KMS.

The check does not show a rewrite by someone who holds the signing key: nothing outside the database is notarised yet.

Not true yet

What this page does not claim.

A security page is read as a commitment. These are the places where the product is behind what a reader might assume.

  1. GuardKin cannot reset your Master Password or your Secret Key.

    Recovery is optional and covers a forgotten Master Password only. Recovery cards are plain shares of the Master Root: any 3 of the 5 rebuild it. If you lose your Secret Key, GuardKin cannot give it back, and the app’s recovery asks you for it. The cards are not a copy of it: they are your key itself, split five ways, so any three open your records for whoever also holds a copy of the stored data. The cards are a deliberate exception: an owner who loses everything still needs a way back. Three card holders alone cannot read your records, because GuardKin gives them none of your data. Three card holders and a copy of the stored data, such as a database dump or a backup, can read all of them. Choose the five with that in mind.

  2. The operator’s second layer covers 3 of 18 routes.

    A database role that was never granted a sealed column backs the operator console on only some of its routes. The others rely on the console’s own list of columns it may select. Moving them behind the role is open work.

  3. No independent cryptography review has been done.

    A review of the key derivation and the sealed-record design by an outside firm is scheduled. No firm is engaged yet, and no findings exist.

  4. No SOC 2 report exists.

    A Type II report is in preparation. The auditor and the observation period are not set, and a Type II covers at least six months.

  5. A bank link passes balances through one server request.

    When an owner links a bank to fill in a balance, the balance passes through a single request to GuardKin’s servers. It is not written to the database, not logged, and no access token is kept. Plaid’s production access is pending, so the customer feature is switched off.

  6. The audit log cannot show a rewrite by someone who holds the signing key.

    Nothing outside the database is notarised yet, so a complete rewrite signed with the real key would verify. The signing key is held in AWS KMS and does not leave it. An outside anchor would close this gap; it is not built.

  7. If GuardKin stopped operating, nothing is arranged for your records.

    There is no source-code escrow, no separate custodian for encrypted data, no escrow of key material and no insured wind-down, and no agreement for any of them has been signed. A wind-down plan exists as an internal draft. It has not been rehearsed.

Send your security team here.

The Trust Center lists what exists, what is in preparation and what is not in place, with the record behind each line.

Security: what we can read, and what we cannot · GuardKin