Skip to content

Latest commit

 

History

History
145 lines (111 loc) · 7.39 KB

File metadata and controls

145 lines (111 loc) · 7.39 KB

Marlin Oyster Logo

Secret store

Oyster Secret Store is a platform designed to securely store user secrets in a highly controlled environment. It is a part of the Oyster web3 ecosystem used to store secret data the users might want to use to run their code on Serverless network. Secret store node is meant to run inside on-chain verified (Oyster-verification protocol) enclave ensuring that any message signed by it will be treated as truth and smart contracts can execute based on that signed message. The owners provide computation services and manage the lifecycle of multiple secret store enclaves, like registration, deregistration, stakes etc. Built using the Rust, Actix Web framework and alloy library - Oyster secret store leverages the power and security of AWS Nitro Enclaves to provide unparalleled isolation and protection for the stored secrets and RPCs to interact with the smart contracts.

Build

Install the following packages :

  • build-essential
  • libc++1
  • libssl-dev
  • musl-tools
  • make
  • pkg-config

Build the secret store binary

Build the binary executable:

cargo build --release

OR (for custom targets)

rustup target add x86_64-unknown-linux-musl
cargo build --release --target x86_64-unknown-linux-musl

Reproducible builds

Reproducible builds can be done using Nix. The monorepo provides a Nix flake which includes this project and can be used to trigger builds:

nix build -v .#<flavor>.serverless.secret-store.<output>

Supported flavors:

  • gnu
  • musl

Supported outputs:

  • default, same as compressed
  • uncompressed
  • compressed, using upx

Usage

Signer file setup

A signer secret is required to run the secret store applicaton. It'll also be the identity of the store enclave on chain i.e, the enclave address will be derived from the corresponding public key. The signer must be a secp256k1 binary secret. The Keygen repo can be used to generate this.

RPC and smart contracts configuration

To run the secret store, details related to RPC like the HTTP and WebSocket URLs will be needed through which the store will communicate with the common chain. Also the addresses of the relevant smart contracts deployed there like SecretStore and SecretManager will be needed.

Run the secret store application :

./target/x86_64-unknown-linux-musl/release/oyster-secret-store --help
Usage: oyster-secret-store [OPTIONS]

Options:
      --port <PORT>                [default: 6002]
        Server port
      --config-file <CONFIG_FILE>  [default: ./oyster_secret_store_config.json]
        Path to the configuration parameters file
  -h, --help                       Print help
  -V, --version                    Print version

Configuration file parameters required for running a secret store node:

{
    "secret_store_path": // Directory path where the secret data files will be created and stored,
    "common_chain_id": // Common chain id,
    "http_rpc_url": // Http url of the RPC endpoint,
    "web_socket_url": // Websocket url of the RPC endpoint,
    "secret_store_contract_addr": // SecretStore smart contract address on common chain,
    "secret_manager_contract_addr": // SecretManager smart contract address on common chain,
    "enclave_signer_file": // path to enclave secp256k1 private key file,
    "acknowledgement_timeout": // Secret inject acknowledgement timeout as configured on common chain (in seconds),
    "mark_alive_timeout": // Secret Store mark alive timeout as configured on common chain (in seconds),
    "num_selected_stores": // Number of stores selected to store an user secret as configured on common chain
}

Example command to run the secret store locally:

sudo ./target/x86_64-unknown-linux-musl/release/oyster-secret-store --port 6002 --config-file ./oyster_secret_store_config.json

Inject immutable configuration parameters into the application:

Currently there is only one such parameter and it is the address of the secret store enclave owner.

$ curl -X POST -H "Content-Type: application/json" -d '{"owner_address_hex": "{OWNER_ADDRESS_HEX}"}' <secret_store_node_ip:secret_store_node_port>/immutable-config
Immutable params configured!

Inject mutable configuration parameters into the application:

Currently there is only one such parameter and it is the gas private key used by the secret store enclave to send transactions to the common chain.

$ curl -X POST -H "Content-Type: application/json" -d '{"gas_key_hex": "{GAS_PRIVATE_KEY_HEX}"}' <secret_store_node_ip:secret_store_node_port>/mutable-config
Mutable params configured!

The owner can use the below endpoint to get details about the state of the secret store node:

$ curl <secret_store_node_ip:secret_store_node_port>/store-details
{"enclave_address":"{ENCLAVE_ADDRESS}","enclave_public_key":"{ENCLAVE_PUBLIC_KEY_HEX}","gas_address":"{ENCLAVE_GAS_ADDRESS}","owner_address":"{ENCLAVE_OWNER_ADDRESS}"}

Exporting registration details from the secret store node:

The owner can hit the below endpoint to get the registration details required to register the secret store enclave on the common chain SecretStore contract. The endpoint will also start the listening of such event notifications on the common chain inside the enclave node.

$ curl <secret_store_node_ip:secret_store_node_port>/signed-registration-message
{"storage_capacity":{SECRET_STORE_CAPACITY_BYTES},"owner":"{STORE_ENCLAVE_OWNER_ADDRESS}","sign_timestamp":{SIGN_TIMESTAMP},"signature":"{ENCLAVE_SIGNATURE_OF_REGISTRATION_DETAILS}"}

Note: After the owner will register the secret store enclave on the common chain, the node will listen to that event and start the listening of user secret requests created by the SecretManager contract on the common chain and store/modify them accordingly.

Injecting secret data into the secret store node:

User after receiving the IP address and public key of the secret store enclaves selected to store their secret can use the below endpoint to inject their encrypted and signed secret data into a secret store node and retrieve the enclave secret stored acknowledgement details.

$ curl -X POST -H "Content-Type: application/json" -d '{"secret_id": {ASSIGNED_SECRET_ID}, "encrypted_secret_hex": "{ENCRYPTED_SECRET_DATA_BYTES_HEX}", "signature_hex": "{USER_SIGNATURE_OF_SECRET_DETAILS}"}' <secret_store_node_ip:secret_store_node_port>/inject-secret
{"secret_id":{SECRET_ID},"sign_timestamp":"{SIGN_TIMESTAMP}","signature":"{ENCLAVE_SIGNATURE_OF_SECRET_ACKNOWLEDGEMENT}"}

Encrypting secret data and signing it:

User can use the following binary to encrypt their secret data bytes with the secret store enclave public key and sign it using their private key with which they requested storage on the common chain.

$ ./target/x86_64-unknown-linux-musl/release/oyster-secret-user-utility --secret-id {SECRET_ID} --secret-data-hex {SECRET_DATA_BYTES_HEX} --enclave-public-key {SECRET_STORE_ENCLAVE_PUBLIC_KEY_HEX} --user-private-hex {USER_PRIVATE_KEY_HEX}
Secret data in bytes: {SECRET_DATA_DECODED_INTO_BYTES}
Secret ID: {SECRET_ID_PROVIDED}
Encrypted secret: {ENCRYPTED_SECRET_DATA_BYTES_HEX}
Signature: {USER_SIGNATURE_OF_SECRET_ID_AND_ENCRYPTED_DATA}

License

This project is licensed under the GNU AGPLv3 or any later version. See LICENSE.txt.