ENTITY Documentation Portal
Core tutorial 4

Protect content without turning storage into authority

ENTITY's encrypted vault stores content under owner/controller control while the governed state keeps commitments and metadata rather than plaintext. Access can then be further constrained by purpose, action, expiry, use count and revocation.

1. Put content into the encrypted vault

vault = EncryptedDataVault(STATE)
item = vault.put_file(
    owner_id,
    "dataset.csv",
    media_type="text/csv",
    classification="PRIVATE",
    metadata={"purpose":"research-source"},
)

The vault uses AES-256-GCM with per-object keys. The returned metadata includes a SHA-256 commitment; plaintext is not written into the ledger/state record.

2. Read as the controller

raw = vault.read_bytes(owner_id, item["vault_object_id"])
assert sha256(raw).hexdigest() == item["content_sha256"]

A controller mismatch fails. A missing key fails. A plaintext commitment mismatch fails.

3. Add a purpose-bound grant

The global privacy layer supports explicit purpose/action grants with expiry and optional use caps.

registry = PurposeBoundAccessRegistry(STATE, identity)
grant = registry.grant(
    owner_id,
    researcher_id,
    resource_ref=item["vault_object_id"],
    purposes=["RESEARCH"],
    actions=["READ"],
    expires_at_ms=EXPIRY_MS,
    max_uses=3,
)

4. Authorize actual use

use = registry.authorize_use(
    grant["grant_id"],
    researcher_id,
    "RESEARCH",
    "READ",
    evidence_sha256=USE_EVIDENCE_SHA256,
)
assert use["authorized"] is True

The implementation rejects inactive grants, wrong grantees, expired grants, wrong purposes, wrong actions and exhausted use caps.

5. Revoke access

registry.revoke(owner_id, grant["grant_id"])

6. Understand vault lifecycle states

The encrypted vault distinguishes ACTIVE, LOCAL_DELETED, CRYPTOGRAPHICALLY_ERASED, REMOTE_DELETION_REQUESTED, REMOTE_DELETION_ATTESTED, REMOTE_DELETION_UNVERIFIED and RETENTION_LEGALLY_REQUIRED.

Important: deleting local ciphertext, destroying a local key and receiving a remote deletion attestation are different events. ENTITY keeps those distinctions instead of declaring “deleted everywhere” without evidence.