input-output-hk / smart-contract-backend

Work in progress: Run off-chain smart contract executables server-side in isolation, accessible via a network interface
Apache License 2.0
8 stars 1 forks source link

Docker Isolation Strategy - Untrusted Code #44

Open Sam-Jeston opened 5 years ago

Sam-Jeston commented 5 years ago

The goal of the application platform is to provide a streamlined approach for Dapp development and to make Dapps as accessible as possible to end users.

The elements of the platform relevant to this issue are:

  1. Client: Responsible for key pair management / access
  2. Server: Interfaces clients to smart contract instances
  3. Isolated execution engine: The engine that runs the smart contracts in an isolated fashion, accessible over HTTP

The roll out of the Application Platform can be considered in 4+ phases:

Phase 1: Proofing the viability of the platform with internal stakeholders. Phase 2: Taking the technology stack to the community for review and early feedback by providing a development stack Phase 3: Providing hosted solutions to allow developers to deploy their contracts as Docker containers to a cloud based environment. This will retain the paradigm of isolated contract execution with a client / server model. Phase 4+: Client-side execution of contracts with a cross-platform runtime (JS / WASM)

For Phase 1, 2 & 3 the mockchain (developed by the Plutus team) and it's associated Wallet API will be used as the EUTxO Client. We are also looking at running contracts in Docker containers for these phases as we do not expect the Haskell -> JS / WASM compilers to be ready.

A recent conversation with @disassembler led to a number of concerns being raised, regarding the running untrusted code in Docker containers.

It's relevant to this issue to understand that for Phase 1, 2 & 3, the isolated execution engine will not be running on client machines, and as such will be completely air-gapped from their keypairs. The execution engine will instead run on isolated instances controlled by IOHK.

For Phase 3, developers from the community need to be able to write Plutus contracts and deploy them to our mockchain stack. This means untrusted code will need to run on our instances. The Application team are looking to work with the Plutus team to have tooling that easily allows developers to create Docker images from their contract code for this phase.

The security considerations of Docker are well described here: https://docs.docker.com/engine/security/security/

As these containers will be running on isolated hardware, only accessible over HTTP, on hardware IOHK control, the risk profile of running untrusted code is greatly reduced. Further to this, the following steps can be taken to protect against malicious container behaviour that may try to abuse the resources of the IOHK provided platform:

  1. The use of control groups to greatly restrict CPU, memory and I/O available to each container
  2. The use of a Kernel hardening solution (AppArmor or similar) to greatly restrict the Kernel features available to the containers. The range of features enabled will need to be discussed with the Plutus team.

It is also important to note that the docker daemon is a well known attack surface, but as this will not be exposed to the containers, this risk is removed.

The security considerations of Phase 4 are outside the scope of this issue.

rhyslbw commented 5 years ago
  1. Server: Interfaces clients to smart contract instances

...over HTTP + web socket

The execution engine will instead run on isolated instances controlled by IOHK

The mockchain is only useful as a local dev tool, so the first deliverable is just the Docker dev stack for trusted code. The hosted services will be needed for a testnet, but that's dependent on a node client that supports the Extended UTXO model and required wallet API endpoints.

Phase 4+: Client side execution of contracts with a cross-platform runtime (JS / WASM) Phase 4: Server-side execution of contracts with a cross-platform runtime (JS / WASM) Phase 5: Service Worker execution

disassembler commented 5 years ago

I would like to add to this, containers should have network acccess in/out completely disabled while running client code. The container should have no network access and return some result on stdout or via a volume map. I still think a proper sandbox is a better solution, but I understand that is being looked into for phase 4.

CharlesMorgan-IOHK commented 5 years ago

Gents, I would like to see the server communication over HTTPS as well, shouldn't be too hard to wrap in something like Let's Encrypt to handle the Certificate management.
Also I agree with Sam's comment above, when dealing with "money", we can never be too paranoid nor too safe -- Charles Morgan

Sam-Jeston commented 5 years ago

Thanks for the input @PolymorphicEngineeringSolutions and @disassembler.

HTTPS will certainly be utilised, that was always our intention, I should have been more specific!

Regarding network access of the containers running the client code @disassembler, we could disable the network, but it'd slightly complicate our orchestration of executing contract methods. A step which may achieve the same thing, but keep the network interface simplicity:

These 2 steps would mean that untrusted code running inside a container can neither make network requests to either the outside world, or any other container in the stack. It would however allow these contract execution containers to listen for incoming execution requests. Let me know your thoughts.