shyconfig manifest
Choose your deployment tier first
Before reading any block reference, pick your tier. Every signing, ledger, and infrastructure choice follows from this.
| Tier | deployment_tier | Chain | Signing | When to use |
|---|---|---|---|---|
| Community | "community" | Shared shyware chain | local_ed25519 (dev) or hosted KMS | Pilots, prototypes, dev — no infra setup required |
| Hosted dedicated | "hosted_dedicated" | Your own chain on shyware infra | AWS KMS (required) | Production — dedicated chain, no ops burden |
| Self-hosted | "self_hosted" | Your own Fabric / AMB chain | AWS KMS (recommended; CloudHSM optional BYOL) | Production — full operator control |
Community is the fastest path. No Hyperledger Fabric node, no KMS key provisioning, no Terraform. Set deployment_tier: "community", ledger_tenancy: "shared", service_hosting: "shyware_hosted", and you are done with infrastructure. The shyware-hosted ledger and API server handle everything else.
Hosted dedicated and self-hosted require the signing infrastructure described in the Signing block and, for self-hosted, the Fabric/AMB provisioning in the Operations section.
What is a shyconfig?
A shyconfig is a machine-readable JSON document that governs a shyware deployment. Every client module validates a shyconfig on initialization and uses it to derive:
- which contract version and flow types are active
- which identity provider and mode to use
- what signing backend configuration to expect
- what deployment posture (recoverable vs. coercion-resistant) applies
- what receipt storage and recovery policy is in effect
- for messaging profiles, what parts of the payload are private versus canonically auditable
Two deployments initialized from shyconfigs with the same contract_version are governed by the same anonymous-layer authority model regardless of branding, hostname, or audience.
The canonical schema is at ShywareLLC/community/schema/shyconfig.schema.json.
For a concrete stress test of the common "anonymous voting + split-record governance"
combination theory, see Prior-Art Combination Stress Test.
Required top-level fields
{
"contract_version": "shyvoting-v1",
"app": { "id": "...", "name": "...", "product_type": "shyvoting" },
"domains": { "public": { "splash": "yourinpolitics.com" } },
"anon_layer": { "sdk_id": "...", "black_box_required": true, "required_flows": [...] },
"api": { "base_url": "https://api.yourdomain.com" },
"identity": { ... },
"signing": { ... },
"deployment": { ... },
"messaging": { ... },
"lots": { ... }
}
contract_version
"shyvoting-v1" | "shywire-v1" | "shycustody-v1" | "shylots-v1" | "shycontracts-v1" | "shyshares-v1" | "shystore-v1" | "shychat-v1" | "shystream-v1" | "shybets-v1" | "shybrowser-v1" | "shyrest-v1"
Determines which embodiment-specific block is required and which required_flows are valid. shyrest-v1 is a composite regulated domain that requires both store and messaging blocks so operators can run sealed personal-state recovery and gated messaging in one contract profile.
Important: shystore-v1 is a regulated domain, not a catch-all default for any deployment that enables shyPayload or shyIDV.
contract_versionselects domain behavior and required config blocks.shyPayloadandshyIDVare capability toggles and may be enabled in multiple domains.- Reusing store semantics in implementation does not imply the deployment should be
shystore-v1.
SDK default behavior for store-backed surfaces:
- if a
storeblock is present, SDK enforcesanon_layer.black_box_required=true - if a
storeblock is present, SDK requires one ofanon_layer.shyPayload=trueoranon_layer.shyIDV=true - if neither toggle is set and
storeis present, SDK defaultsanon_layer.shyPayload=true - for
shystream-v1, SDK defaultsanon_layer.required_flowsto includehop_route_storeandhop_route_reveal
Domain selection quick guide
| If your primary product workload is... | Choose this contract_version | Why |
|---|---|---|
| Sealed personal secrets/credentials with recovery and selective disclosure | shystore-v1 | Native store domain; canonical focus is secret lifecycle and recovery auditability. |
| Streaming/media operator workflows with sealed metadata and playback/ingest controls | shystream-v1 | Stream domain with required stream block, store-style sealing defaults, and hop route-flow defaults. |
| Sealed mailbox/dispatch workflows as the primary surface | shychat-v1 | Messaging domain for mailbox lifecycle and delivery audit semantics. |
| Combined personal secret lifecycle + mailbox/dispatch in one governed profile | shyrest-v1 | Composite domain requiring both store and messaging blocks. |
Implementation status notes:
shycontracts-v1is a general anonymous smart contracts platform. Revenue-based financing (RBF) is onecontractTypeconfiguration. Thecontractsblock (orfinancingfor backwards compat) declares the transfer layer; domain-specific fields go inmetadatainside each registered contract.shycam,shyIoT, andshyhopare first-class utility clients over store semantics, not standalone regulated domains at this stage.shylotsis now a standalone regulated auctions profile (shylots-v1).
anon_layer.required_flows
Declares the SDK flow types this deployment activates. Full set by embodiment:
| Embodiment | SDK-enforced required flows | Notes |
|---|---|---|
shyvoting | poll_read, ballot_build, ballot_submit, receipt_verify | identity_bind is conventional but not SDK-enforced; receipts.match_store and receipts.double_vote_enforcement are required; identity.provider must not be "none" |
shystore | (none checked by SDK) | Requires anon_layer.shyPayload: true or anon_layer.shyIDV: true |
shychat | (none checked by SDK) | Requires identity.surface_model: "mail"|"chat" and domains.private.console |
shyrest | secret_store, secret_retrieve, secret_delete, biometric_rederive, mailbox_read, mailbox_create, dispatch_queue, dispatch_close, receipt_verify | |
shystream | stream_event, stream_clip, stream_read, biometric_rederive, hop_route_store, hop_route_reveal | Also requires store block, stream.provider, domains.private.console, signing.required |
shybrowser | (none checked by SDK) | No required_flows validation; only enforces sealer.mode: "sealed_storage" |
shywire | wire_issue, wire_transfer, wire_redeem | |
shycustody | policy_read, lot_record, silo_transfer, redemption_request, redemption_settlement, demurrage_apply, cam_attest_store, cam_attest_reveal, stream_event, stream_clip, stream_read | |
shylots | all shycustody flows + wire_issue, wire_transfer, wire_redeem | |
shycontracts | contract_register, contract_activate, contract_execute | |
shyshares | organization_read, membership_snapshot_read, proposal_create, weighted_ballot_submit, tally_read, action_queue_read, action_dispatch |
For store-backed clients (shystore, shychat, shyrest, shystream), assertStoreBackedAnonLayer additionally requires anon_layer.black_box_required: true and either anon_layer.shyPayload: true or anon_layer.shyIDV: true. applyStoreAnonLayerDefaults sets these automatically if the store block is present and the toggles are absent.
Identity block
"identity": {
"provider": "didit",
"mode": "stable_person_id",
"kyc_required": true,
"recommended_idv": "didit",
"byoid_policy": "disallowed",
"workflow_id": "...",
"issuer_did": "did:prism:..."
}
| Field | Values | Notes |
|---|---|---|
provider | didit | identus | wallet | none | Primary identity source |
mode | stable_person_id | wallet_commitment | manual_demo | Commitment derivation strategy |
surface_model | mail | chat | Only used by messaging profiles such as shychat |
account_model | single_account | multi_account | Whether the deployment treats the participant as a single mailbox principal or permits multiple mailbox/account scopes |
participant_binding | string | Human-readable binding mode, e.g. scoped_commitment_optional |
byoid_policy | disallowed | allowed | required | Whether to accept caller-supplied identity inputs |
presentation_mode | proof_hash | credential_commitment | wallet_signature | How identity proof is presented to the runtime |
Signing block
The managed key service signs the period-close attestation over dual Merkle roots (|L1(S)|, |L2(S)|); every signing invocation is recorded in the provider's audit log with write-once retention — tamper-evident by platform guarantee. Any third party with the public key can independently verify aggregate correctness without running a node or trusting the operator.
The pattern is provider-agnostic:
| Provider | Signing | Audit log | Write-once retention |
|---|---|---|---|
| AWS | KMS (AwsKmsSigningInterface) | CloudTrail | S3 Object Lock (COMPLIANCE mode) |
| GCP | Cloud KMS (GcpKmsSigningInterface) | Cloud Audit Logs | Cloud Storage retention lock |
| Azure | Key Vault (AzureKeyVaultSigningInterface) | Azure Monitor activity logs | Immutable blob storage policy |
| Self-hosted | Vault Transit (VaultSigningInterface) | Vault audit device | Must be explicitly enabled and routed to write-once storage |
All managed cloud providers (AWS, GCP, Azure) record signing invocations automatically at the platform level — no adapter configuration required. Vault audit logging must be explicitly enabled; without it the write-once guarantee does not hold.
"signing": {
"required": true,
"backend": "aws_kms",
"validator_key_id": "alias/shyware-validator",
"tally_key_id": "alias/shyware-tally",
"attestation_required": true
}
backend | Use case |
|---|---|
aws_kms | Production |
local_ed25519 | Development only |
none | Testing without signing |
Deployment block
"deployment": {
"deployment_tier": "community",
"ledger_tenancy": "shared",
"service_hosting": "shyware_hosted",
"reconcile_mode": "operator_read_only",
"default_posture": "recoverable",
"runtime_fallbacks": {
"write_only_on_missing_play_integrity": true,
"write_only_on_hostile_network": true,
"write_only_on_untrusted_device_attestation": true
}
}
default_posture: "coercion_resistant" activates write-only mode unconditionally — no receipt retained on device after submission. "recoverable" allows receipt retention when runtime signals indicate a safe environment, falling back to write-only when any enabled runtime fallback condition is met.
| Field | Values | Notes |
|---|---|---|
deployment_tier | community | hosted_dedicated | self_hosted | Commercial/operational tier. community is the shared-chain onramp for dev, pilots, and light production. |
ledger_tenancy | shared | dedicated | Whether canonical state lands on a shared chain or tenant-dedicated chain. |
service_hosting | shyware_hosted | tenant_hosted | Who runs APIs, consoles, dispatch, and other service surfaces. |
reconcile_mode | operator_read_only | user_only | disabled | High-level recovery/reconcile posture. |
runtime_fallbacks.write_only_on_missing_play_integrity | boolean | Forces write-only when Play Integrity token is absent or fails verification. |
runtime_fallbacks.write_only_on_hostile_network | boolean | Forces write-only when the runtime detects a hostile network environment. |
runtime_fallbacks.write_only_on_untrusted_device_attestation | boolean | Forces write-only when device attestation is unavailable or fails. |
These axes let the same invariant run as:
- a shared-chain community service at
community.shyware.fyi - a shyware-hosted but tenant-dedicated deployment
- or a fully self-hosted tenant chain
without changing the anonymous-layer state machine.
Messaging block
"messaging": {
"payload_model": "sealed_private_content",
"audit_model": "delivery_commitment_only",
"allowed_payload_formats": ["mail_text", "json_form", "report_packet"]
}
| Field | Values | Notes |
|---|---|---|
payload_model | sealed_private_content | Content, structured private fields, and attachment references stay off-canonical |
audit_model | delivery_commitment_only | delivery_metadata_commitment | Whether canonical audit includes only commitments and delivery windows, or also safe descriptors such as content class and payload format |
allowed_payload_formats | string[] | UI / SDK allowlist for format-specific private payload builders |
Receipts block
"receipts": {
"match_store": "cockroach_encrypted",
"user_access": "gated_recovery",
"double_vote_enforcement": "voter_registry_only",
"recovery_signals": ["device_integrity", "didit_recheck"],
"high_risk_region_blocklist": ["IR", "KP", "RU"]
}
match_store | Notes |
|---|---|
cockroach_encrypted | Production — encrypted CockroachDB on Verne Global |
firestore_encrypted | Production — encrypted Firestore |
device_only | Receipt stored locally only; no reconcile available |
none | Write-only — no receipt retained |
Embodiment-specific blocks
shyvoting — no additional domain block; receipts required
assertVotingManifest requires receipts.match_store, receipts.double_vote_enforcement, deployment.default_posture, deployment.runtime_fallbacks, and signing.required: true. identity.provider must not be "none".
Full example:
{
"contract_version": "shyvoting-v1",
"app": {
"id": "youinpolitics",
"name": "YouInPolitics",
"product_type": "shyvoting",
"chain_id": "shyware-1"
},
"api": { "base_url": "https://api.youinpolitics.com" },
"anon_layer": {
"sdk_id": "shyware-web-v1",
"black_box_required": true,
"required_flows": ["poll_read", "ballot_build", "ballot_submit", "receipt_verify"]
},
"identity": {
"provider": "didit",
"mode": "stable_person_id",
"kyc_required": true,
"recommended_idv": "didit",
"byoid_policy": "disallowed",
"workflow_id": "<didit-workflow-id>",
"issuer_did": "did:prism:..."
},
"signing": {
"required": true,
"backend": "aws_kms",
"validator_key_id": "alias/shyware-validator",
"tally_key_id": "alias/shyware-tally"
},
"deployment": {
"deployment_tier": "hosted_dedicated",
"ledger_tenancy": "dedicated",
"service_hosting": "shyware_hosted",
"reconcile_mode": "operator_read_only",
"default_posture": "recoverable",
"runtime_fallbacks": {
"write_only_on_missing_play_integrity": true,
"write_only_on_hostile_network": true,
"write_only_on_untrusted_device_attestation": true,
}
},
"receipts": {
"match_store": "cockroach_encrypted",
"user_access": "gated_recovery",
"double_vote_enforcement": "voter_registry_only",
"recovery_signals": ["device_integrity", "didit_recheck"],
"high_risk_region_blocklist": ["IR", "KP", "RU"]
}
}
shychat — messaging domain (shychat-v1)
{
"contract_version": "shychat-v1",
"app": {
"id": "shychat",
"name": "Scytale",
"product_type": "shychat",
"chain_id": "shyware-1"
},
"identity": {
"provider": "none",
"surface_model": "mail",
"account_model": "multi_account",
"participant_binding": "scoped_commitment_optional"
},
"messaging": {
"payload_model": "sealed_private_content",
"audit_model": "delivery_commitment_only",
"allowed_payload_formats": ["mail_text", "json_form", "review_packet"]
},
"deployment": {
"deployment_tier": "community",
"ledger_tenancy": "shared",
"service_hosting": "shyware_hosted",
"reconcile_mode": "operator_read_only",
"default_posture": "recoverable",
"attestation": { "mode": "period_close" }
}
}
shychat uses the same consensus-level non-materialization profile as shyvoting-v1, but replaces ballot/direction UX with mailbox, dispatch, intake, and sealed-submission surfaces. The canonical audit surface can remain limited to delivery continuity and payload commitments even when the actual payload is PII-bearing and must stay sealed off-canonical.
That makes it a natural fit for the community tier: tenants can launch on a shared chain with their own subdomain and manifest first, then graduate to hosted_dedicated or self_hosted later without changing the underlying claim-bearing invariant.
shyrest — composite store + messaging under shyrest-v1
{
"contract_version": "shyrest-v1",
"app": {
"id": "informant-stream",
"name": "informant.stream",
"product_type": "shyrest",
"chain_id": "review-1"
},
"identity": {
"provider": "didit",
"mode": "stable_person_id"
},
"anon_layer": {
"sdk_id": "shyware-web-v1",
"black_box_required": true,
"required_flows": [
"secret_store",
"secret_retrieve",
"secret_delete",
"biometric_rederive",
"mailbox_read",
"mailbox_create",
"dispatch_queue",
"dispatch_close",
"receipt_verify"
]
},
"store": {
"secret_categories": ["review_submission", "health_record", "arbitrary"],
"payload_encryption": {
"mode": "participant_derived_key",
"kdf": "hkdf_sha256"
},
"recovery_mode": "biometric_rederivation",
"selective_disclosure": true,
"enumeration_protection": "structural"
},
"messaging": {
"payload_model": "sealed_private_content",
"audit_model": "delivery_commitment_only",
"allowed_payload_formats": ["mail_text", "json_form", "review_packet"],
"mailbox_model": "multi_mailbox",
"delivery_model": "dispatch_queue",
"retention_policy": "mailbox_lifetime"
}
}
shyrest-v1 is for deployments that need both sealed personal state and gated mailbox flows in one regulated-domain contract profile. It keeps one manifest and one authority matrix while exposing both store and chat client surfaces.
Web SDK bootstrap for a shyrest deployment:
import { createStoreClient } from '@shyware/sdk/clients/store';
import { createChatClient } from '@shyware/sdk/clients/chat';
const shyconfig = await fetch("/shyconfig.json").then((r) => r.json());
const getAuthHeaders = async () => ({
Authorization: `Bearer ${localStorage.getItem("authToken") || ""}`
});
export const store = createStoreClient({
defaultBase: shyconfig.api?.base_url ?? "/api",
getAuthHeaders,
manifest: shyconfig
});
export const chat = createChatClient({
defaultBase: shyconfig.api?.base_url ?? "/api",
getAuthHeaders,
manifest: shyconfig
});
// Example composite usage: seal/recover secret state and dispatch mailbox payloads.
await store.storeSubmission({
scopingId: "intake-q2-2026",
plaintext: { title: "Draft" },
category: "review_submission"
});
await chat.queueDispatch({
mailboxId: "case-intake",
recipientAddress: "intake@informant.stream",
subject: "Submission received",
body: "Submission received",
contentClass: "review_packet",
payloadFormat: "mail_text"
});
shywire — wire block required
Full example:
{
"contract_version": "shywire-v1",
"app": {
"id": "oneway-wire",
"name": "Oneway",
"product_type": "shywire",
"chain_id": "shyware-1"
},
"api": { "base_url": "https://api.oneway.wiki" },
"anon_layer": {
"sdk_id": "shyware-web-v1",
"black_box_required": true,
"required_flows": ["wire_issue", "wire_transfer", "wire_redeem"]
},
"identity": {
"provider": "wallet",
"mode": "wallet_commitment"
},
"signing": {
"required": true,
"backend": "aws_kms",
"validator_key_id": "alias/shyware-validator",
"tally_key_id": "alias/shyware-tally"
},
"deployment": {
"deployment_tier": "hosted_dedicated",
"ledger_tenancy": "dedicated",
"service_hosting": "shyware_hosted",
"reconcile_mode": "operator_read_only",
"default_posture": "recoverable"
},
"wire": {
"asset_id": "usdc-shywire",
"issuer_name": "Oneway",
"backing_asset": "USDC",
"wrapper_mode": "stablecoin_wrapper",
"provider": "circle_usdc",
"provider_config": {
"mode": "live",
"intent_path": "/wire/intent",
"settlement_asset": "USDC",
"supported_rails": ["blockchain", "ach"],
"requires_operator_review": false
},
"operator_mint_burn": true,
"reconcile_authority": "issuer_read_only",
"supported_networks": ["ethereum", "polygon"]
}
}
identity.provider must be "wallet" for wire deployments — account commitments are derived from wallet addresses, not IDV person IDs. reconcile_authority: "issuer_read_only" gives the stablecoin issuer (Circle) read access for AML/OFAC compliance without write authority over canonical state.
shycustody — custody, store, and stream blocks required
assertCustodyManifest throws if store or stream blocks are absent — they are required for shycam sealed evidence and shystream lot-intake video, even if those surfaces are not exposed in the UI.
Full example:
{
"contract_version": "shycustody-v1",
"app": {
"id": "vaults-biz",
"name": "Vaults",
"product_type": "shycustody",
"chain_id": "shyware-1"
},
"api": { "base_url": "https://api.vaults.biz" },
"anon_layer": {
"sdk_id": "shyware-web-v1",
"black_box_required": true,
"required_flows": [
"policy_read", "lot_record", "silo_transfer",
"redemption_request", "redemption_settlement", "demurrage_apply",
"cam_attest_store", "cam_attest_reveal",
"stream_event", "stream_clip", "stream_read"
]
},
"identity": {
"provider": "wallet",
"mode": "wallet_commitment"
},
"signing": {
"required": true,
"backend": "aws_kms",
"validator_key_id": "alias/shyware-validator",
"tally_key_id": "alias/shyware-tally"
},
"deployment": {
"deployment_tier": "hosted_dedicated",
"ledger_tenancy": "dedicated",
"service_hosting": "shyware_hosted",
"reconcile_mode": "operator_read_only",
"default_posture": "recoverable"
},
"custody": {
"asset_id": "vault-gold-1",
"policy_source": "on_chain",
"accepted_sku_whitelist": ["XAU-9999", "XAU-9995"],
"unit_of_measure": "troy_oz",
"quantity_normalization": "grade_weight_nav",
"demurrage_policy": "policy_burn",
"operator_mint_burn": true,
"redemption_mode": "physical_goods_only",
"redemption_routing": "holder_chooses_warehouse",
"evidence_requirements": ["camera_session_ref", "operator_receipt_ref"],
"transfer_layer": "shywire"
},
"store": {
"secret_categories": ["lot_evidence", "arbitrary"],
"payload_encryption": { "mode": "participant_derived_key", "kdf": "hkdf_sha256" },
"recovery_mode": "biometric_rederivation"
},
"stream": {
"stream_mode": "operator_attested",
"allowed_content_classes": ["lot_intake_video", "inspection_clip"]
}
}
All eleven required flows must be declared. cam_attest_store / cam_attest_reveal gate the shycam evidence sealing path; stream_event / stream_clip / stream_read gate intake video. The SDK throws at initialization if any flow is missing.
shylots — standalone regulated auctions domain (shylots-v1)
{
"contract_version": "shylots-v1",
"app": {
"id": "shylots",
"name": "Shylots",
"product_type": "shylots",
"chain_id": "shyware-1"
},
"custody": {
"asset_id": "lot-unit",
"policy_source": "on_chain",
"accepted_sku_whitelist": ["warehouse_lot"],
"unit_of_measure": "lot",
"quantity_normalization": "whole_lot",
"demurrage_policy": "policy_burn",
"redemption_mode": "physical_goods_only",
"redemption_routing": "holder_chooses_warehouse",
"evidence_requirements": ["camera_session_ref", "operator_receipt_ref"],
"transfer_layer": "shywire"
},
"wire": {
"asset_id": "usd-lot",
"issuer_name": "Shylots Settlement",
"backing_asset": "USD",
"provider": "custom",
"provider_config": {
"mode": "sandbox",
"intent_path": "/wire-provider",
"settlement_asset": "USD",
"supported_rails": ["blockchain", "ach"],
"requires_operator_review": true
},
"supported_networks": ["base-sepolia"]
},
"lots": {
"market_operator": "operator-west",
"sale_modes": ["sealed_bid"],
"open_mode": "operator_attested_close",
"bid_visibility": "sealed_until_close",
"reserve_funding_mode": "bid_bond_transfer",
"settlement_asset_id": "usd-lot"
}
}
Shylots is a separate auctions contract version that composes:
shycustodysemantics for canonical lot records, policy, evidence references, and redemptionshywirerails for bidder funding, bid bonds, award settlement, and payout/refund rails- the
lotsblock for product semantics such as sale mode, visibility posture, and settlement asset
shycontracts — contracts block required
Full example:
{
"contract_version": "shycontracts-v1",
"app": {
"id": "vau-contracts",
"name": "VAU",
"product_type": "shycontracts",
"chain_id": "shyware-1"
},
"api": { "base_url": "https://api.vau.money" },
"anon_layer": {
"sdk_id": "shyware-web-v1",
"black_box_required": true,
"required_flows": ["contract_register", "contract_activate", "contract_execute"]
},
"identity": {
"provider": "wallet",
"mode": "wallet_commitment"
},
"signing": {
"required": true,
"backend": "aws_kms",
"validator_key_id": "alias/shyware-validator",
"tally_key_id": "alias/shyware-tally",
"contract_key_id": "alias/shyware-contract"
},
"deployment": {
"deployment_tier": "hosted_dedicated",
"ledger_tenancy": "dedicated",
"service_hosting": "shyware_hosted",
"reconcile_mode": "operator_read_only",
"default_posture": "recoverable"
},
"contracts": {
"transfer_layer": "shywire"
}
}
signing.contract_key_id is required for KMS backends — the SDK throws at initialization if absent. contracts.transfer_layer: "shywire" is optional; declare it when contract executions move value. The financing key is accepted as an alias for contracts for backwards compatibility. Domain-specific fields (RBF interest rates, custody terms, etc.) go in each contract's metadata at registration time, not in the shyconfig.
shyshares — governance + execution blocks required
Both blocks are hard-enforced by assertSharesManifest. governance.transfer_layer is optional — declare "shywire" to use the built-in anonymous transfer rail for governance token balance and stake transfers, or omit it to supply your own.
Full example:
{
"contract_version": "shyshares-v1",
"app": {
"id": "bigglom-governance",
"name": "Bigglom",
"product_type": "shyshares",
"chain_id": "shyware-1"
},
"api": { "base_url": "https://api.bigglom.com" },
"anon_layer": {
"sdk_id": "shyware-web-v1",
"black_box_required": true,
"required_flows": [
"organization_read", "membership_snapshot_read",
"proposal_create", "weighted_ballot_submit",
"tally_read", "action_queue_read", "action_dispatch"
]
},
"identity": {
"provider": "wallet",
"mode": "wallet_commitment"
},
"signing": {
"required": true,
"backend": "aws_kms",
"validator_key_id": "alias/shyware-validator",
"tally_key_id": "alias/shyware-tally"
},
"deployment": {
"deployment_tier": "hosted_dedicated",
"ledger_tenancy": "dedicated",
"service_hosting": "shyware_hosted",
"reconcile_mode": "operator_read_only",
"default_posture": "recoverable"
},
"governance": {
"membership_sources": ["token_balance"],
"weighting_mode": "token_weighted",
"privacy_mode": "anonymous",
"proposal_classes": ["parameter_change", "treasury_payout"],
"transfer_layer": "shywire"
},
"execution": {
"default_mode": "internal_queue",
"adapters": ["shywire"],
"canonical_queue": true
}
}
identity.provider: "wallet" — member commitments are derived from wallet addresses. When governance.transfer_layer: "shywire" is declared, a separate wireClient initialized with a shywire-v1 shyconfig handles token setup and stake transfers. Omit transfer_layer to use your own payment system. deriveSealerKey can be passed to initializeFromShyConfig if sealer.enabled: true is set in the shyconfig for sealed proposal payloads.
shybrowser — sealer block required
shybrowser-v1 requires a sealer block declaring sealed storage mode. Both List 1 (payload) and List 2 (identity attribute) are sealed by the operator-supplied sealer key before canonical write.
"sealer": {
"mode": "sealed_storage"
}
shystore — store block required
assertStoreManifest requires store block and domains.private.console. Requires anon_layer.shyPayload: true or anon_layer.shyIDV: true (applied automatically via applyStoreAnonLayerDefaults if absent).
Full example:
{
"contract_version": "shystore-v1",
"app": { "id": "health-vault", "name": "Health Vault", "product_type": "shystore", "chain_id": "shyware-1" },
"api": { "base_url": "https://api.health-vault.example" },
"domains": { "private": { "console": "console.health-vault.example" } },
"anon_layer": {
"sdk_id": "shyware-web-v1",
"black_box_required": true,
"shyPayload": true
},
"identity": { "provider": "didit", "mode": "stable_person_id", "kyc_required": true },
"signing": { "required": true, "backend": "aws_kms", "tally_key_id": "alias/shyware-tally" },
"deployment": { "deployment_tier": "hosted_dedicated", "default_posture": "recoverable" },
"store": {
"secret_categories": ["health_record", "auth_seed_totp", "arbitrary"],
"recovery_mode": "biometric_rederivation",
"payload_encryption": { "mode": "participant_derived_key", "kdf": "hkdf_sha256" },
"selective_disclosure": true,
"enumeration_protection": "structural"
}
}
shychat — messaging block required
assertChatManifest requires messaging block, identity.surface_model: "mail" | "chat", and domains.private.console.
Full example:
{
"contract_version": "shychat-v1",
"app": { "id": "secure-inbox", "name": "Secure Inbox", "product_type": "shychat", "chain_id": "shyware-1" },
"api": { "base_url": "https://api.secure-inbox.example" },
"domains": { "private": { "console": "console.secure-inbox.example" } },
"anon_layer": { "sdk_id": "shyware-web-v1", "black_box_required": true, "shyPayload": true },
"identity": {
"provider": "none",
"surface_model": "mail",
"account_model": "multi_account",
"participant_binding": "scoped_commitment_optional"
},
"messaging": {
"payload_model": "sealed_private_content",
"audit_model": "delivery_commitment_only",
"allowed_payload_formats": ["mail_text", "json_form"],
"mailbox_model": "multi_mailbox",
"delivery_model": "dispatch_queue",
"retention_policy": "mailbox_lifetime"
},
"deployment": { "deployment_tier": "community", "default_posture": "recoverable",
"attestation": { "mode": "period_close" } }
}
shybrowser — sealer block required
assertBrowserManifest only enforces sealer.mode: "sealed_storage". No anon_layer, no required_flows, no domains check.
{
"contract_version": "shybrowser-v1",
"app": { "id": "analytics", "product_type": "shybrowser" },
"sealer": { "mode": "sealed_storage" }
}
shystore — store block reference
The store block governs secret categories, recovery mode, and sealing policy for shystore-v1, shyrest-v1, shystream-v1, and shychat-v1 deployments.
"store": {
"secret_categories": ["auth_seed_totp", "auth_seed_fido2", "health_record", "arbitrary"],
"recovery_mode": "operator_sealer",
"payload_encryption": { "mode": "participant_derived_key" },
"sealer": { "mode": "sealed_storage" },
"ehr_provider": "epic",
"selective_disclosure": true,
"enumeration_protection": "structural"
}
| Field | Values | Notes |
|---|---|---|
secret_categories | string array | Allowed SecretStoreData.Category values per bucket |
recovery_mode | biometric_rederivation | operator_sealer | operator_sealer = Cognito primary + biometric break-glass |
payload_encryption.mode | participant_derived_key | AES-GCM sealing client-side before broadcast |
ehr_provider | epic | custom | Activates schedule-health DPA; enables SMART on FHIR import |
selective_disclosure | boolean | Scoped FHIR resource-type disclosure in reconcile API |
enumeration_protection | structural | No system-defined query yields a cross-participant listing |
Surface routing
resolveAppSurface reads the domains block and determines whether the current page is on the public or private surface.
import { resolveAppSurface } from '@shyware/sdk/utils/hostRouting'
const surface = resolveAppSurface(shyconfig)
// → "public" | "private"
// With explicit hostname (e.g. SSR):
const surface = resolveAppSurface(shyconfig, { hostname: req.hostname })
// Allow ?console query override in dev:
const surface = resolveAppSurface(shyconfig, { allowQueryOverride: true })
Returns "private" when the current hostname matches domains.private.vote or domains.private.console. Returns "public" otherwise. When allowQueryOverride: true, the query string ?console also triggers "private" — useful during development when the private surface runs on the same origin as the public one.