Creating a Service
Now that we've a simple API working locally, let's make it into a service. The steps are:
- Log into the Oblivious console.
- Connect your repository and specify it's behavior.
- 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):
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.
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:
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