Skip to main content

Creating a Service

Now that we've a simple API working locally, let's make it into a service. The steps are:

  1. Log into the Oblivious console.
  2. Connect your repository and specify it's behavior.
  3. Add a slightly modified Dockerfile & service executables to launch at runtime

Log into the Oblivious console

To log into the Oblivious console with GitHub, simply go to https://console.oblivious.ai and hit the GitHub icon (highlighted in red below):

Login Screenshot

All of your repositories will now be in the Repositories folder. Use the search feature to find my-first-oblivious-app and click on the title.

Repository Search Screenshot

Connect your repository and specify it's behaviour

Once you've clicked into the repository, you should see the source code, similar to viewing the repository on GitHub. We'll now click the "Add a Service" button as shown in red below:

Add Service Screenshot

You'll now be asked to fill in a form that specifies the services behavior. For this simple Hello World application, we will be using the following configuration:

Base Image: python 3-8

# How you will authenticate the users
Auth Name: default
Auth Type: signed_headers

# At least 1 role for users
Role Name: querier
Role Description: The people who will be greeted
Role Cardinality: 1
Role Auth: default

# List the paths available and who can access them (we'll only use 1 root path)
Path: /say_hello
Access: querier
Short Description: Responds "Hello" and their name

# Build Arguments (we don't have any for this application)

# Traffic
Port: 80
Name: inbound

# Meta
Author: Example User
Email: example@oblivious.ai
git: https://github.com/ObliviousAI/my-first-oblivious-app.git
version: 0.1.0

Once filled in, simply hit Submit & Create. If there is a validation error the form will let you know what it is. When successfully submitted, you'll see the new service in the Service tab and you'll notice a .oblivious folder created in your repository.

Add a slightly modified Dockerfile & service executables to launch at runtime

As explained here, enclaves are complex virtual machines, not typical docker containers. As such, we've put in a number of fixed services which support you application to run inside the enclave. However, this requires slight modifications to how your Dockerfile should be layed out.

First we need to copy your Dockerfile inside of the .oblivious folder and remove the line with CMD or Entrypoint

FROM python:3.9

WORKDIR /code

COPY ./requirements.txt /code/requirements.txt

RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt

COPY ./api.py /code/api.py

# Commented out CMD line
# CMD ["uvicorn", "api:app", "--host", "0.0.0.0", "--port", "80"]

The FROM line will be replaced with a variant of the base image we selected in the previous step (python 3-8 in our case).

Next, we need the enclave to know how to actually run our service. Internally, this is managed by the s6 service manager, so it requires us to create an executable for each sub-service (program) we want to run. These are placed in a new folder called .oblivious/services/<service neme>. Let's add our service now by creating a folder called .oblivious/services/server/ and adding the following file named run in it (note no .sh or equivalent extension):

#!/bin/sh
cd /code/
uvicorn api:app --host 0.0.0.0 --port 80

One of the benefits of using s6 is that if our server were to clash, it will be gracefully restarted inside the enclave with limited downtime. When these steps are complete, push your code to GitHub so the changes can be updated.

Your repository should have the following structure:

โ”œโ”€โ”€ .oblivious
โ”‚ โ”œโ”€โ”€ Dockerfile
โ”‚ โ”œโ”€โ”€ service.yaml
โ”‚ โ””โ”€โ”€ services
โ”‚ โ””โ”€โ”€ server
โ”‚ โ””โ”€โ”€ run
โ”œโ”€โ”€ api.py
โ”œโ”€โ”€ requirements.txt
โ”œโ”€โ”€ Dockerfile
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ .gitattributes
โ””โ”€โ”€ .gitignore