Skip to main content

Run untrusted commands in a sandbox.

Project description

Sandcastle Build Status

Run untrusted code in a castle (OpenShift pod), which stands in a sandbox.

Usage

The prerequisite is that you're logged in an OpenShift cluster:

$ oc status
 In project Local Project (myproject) on server https://localhost:8443

The simplest use case is to invoke a command in a new openshift pod:

from sandcastle import Sandcastle

s = Sandcastle(
    image_reference="docker.io/this-is-my/image:latest",
    k8s_namespace_name="myproject"
)
output = s.run(command=["ls", "-lha"])

These things will happen:

  • A new pod is created, using the image set in image_reference.
  • The library actively waits for the pod to finish.
  • If the pod terminates with a return code greater than 0, an exception is raised.
  • Output of the command is return from the .run() method.

Sharing data between sandbox and current pod

This library allows you to share volumes between the pod it is running in and between sandbox.

There is a dedicated class and an interface to access this functionality:

  • VolumeSpec class
  • volume_mounts kwarg of Sandcastle constructor

An example is worth of thousand words:

from pathlib import Path
from sandcastle import Sandcastle, VolumeSpec

# the expectation is that volume assigned to PVC set
# via env var SANDCASTLE_PVC is mounted in current pod at /path
vs = VolumeSpec(path="/path", pvc_from_env="SANDCASTLE_PVC")

s = Sandcastle(
    image_reference="docker.io/this-is-my/image:latest",
    k8s_namespace_name="myproject",
    volume_mounts=[vs]
)
s.run()
s.exec(command=["bash", "-c", "ls -lha /path"])    # will be empty
s.exec(command=["bash", "-c", "mkdir /path/dir"])  # will create a dir
assert Path("/path/dir").is_dir()                  # should pass

Sharing data by copying them

Sandcastle is able to run the sandbox pod in a different namespace. This improves security since it's trivial to lock networking of this project down - the pod won't be able to access OpenShift API server nor any of your services deployed in the cluster. For more info, check out egress rules and network policy.

When you set up this sandbox namespace, please make sure that service account of namespace your app is deployed in can manage pods in the sandbox namespace. This command should help:

$ oc adm -n ${SANDBOX_NAMESPACE} policy add-role-to-user edit system:serviceaccount:${APP_NAMESPACE}:default

Real code:

m_dir = MappedDir(
    local_dir,             # share this dir
    sandbox_mountpoint,    # make it available here
    with_interim_pvc=True  # the data will be placed in a volume
)

o = Sandcastle(
    image_reference=container_image,
    k8s_namespace_name=namespace,      # can be a different namespace
    mapped_dir=m_dir,
    working_dir=sandbox_mountpoint,
)
o.run()
# happy execing
o.exec(command=["ls", "-lha", f"{sandbox_mountpoint}/"])

Developing sandcastle

In order to develop this project (and run tests), there are several requirements which need to be met.

  1. Build container images using makefile target make test-image-build.

  2. An openshift cluster and be logged into it

    Which means that running oc status should yield the cluster where you want to run the tests.

    The e2e test test_from_pod builds current codebase and runs the other e2e tests in a pod: to verify the E2E functionality. This expects that the openshift cluster is deployed in your current environment, meaning that openshift can access your local container images in your dockerd. Otherwise the image needs to be pushed somewhere so openshift can access it.

  3. In the default oc cluster up environment, the tests create sandbox pod using the default service account which is assigned to every pod. This SA doesn't have permissions to create nor delete pods (so the sandboxing would not work). With this command, the SA is allowed to change any objects in the namespace:

    oc adm policy add-role-to-user edit system:serviceaccount:myproject:default
    
  4. Docker binary and docker daemon running. This is implied from the first point.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sandcastle-0.1.0.tar.gz (24.1 kB view details)

Uploaded Source

Built Distribution

sandcastle-0.1.0-py3-none-any.whl (17.0 kB view details)

Uploaded Python 3

File details

Details for the file sandcastle-0.1.0.tar.gz.

File metadata

  • Download URL: sandcastle-0.1.0.tar.gz
  • Upload date:
  • Size: 24.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.2 pkginfo/1.4.2 requests/2.21.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.28.1 CPython/3.7.3

File hashes

Hashes for sandcastle-0.1.0.tar.gz
Algorithm Hash digest
SHA256 71aea7b740b4f42acfd997d56fd4d408cc887437079c0f721ea92cb6d5eeb513
MD5 8ea7f64e3e44b8b83022e129773ce82a
BLAKE2b-256 67f50be9a151a3aac5ace0d508c612943cce1dbae87614db4de107a164c4613f

See more details on using hashes here.

Provenance

File details

Details for the file sandcastle-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: sandcastle-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 17.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.2 pkginfo/1.4.2 requests/2.21.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.28.1 CPython/3.7.3

File hashes

Hashes for sandcastle-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ef4e2d64838d4d3e7ce4003c13cee7e0b3e1ff2771182e7011678ffada8c9e74
MD5 ad7348dd35c8ba54090e18db28728c66
BLAKE2b-256 7c7b939c2f2a584c54b5887a64e243b35bec2548a9d6cfae1702c483f1415adb

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page