Commit 61cd24d9 authored by Robert Schambach's avatar Robert Schambach
Browse files

Make small policy tweaks and add TLS section to readme

parent 65dee484
......@@ -21,6 +21,9 @@ services:
command: ["python3", "rest_api.py"]
mrenclaves: ["$MRENCLAVE_SIMPLECLIENT_FASTAPI"]
pwd: /
fspf_path: /fspf.pb
fspf_key: $FASTAPI_POLICY_FSPF_KEY
fspf_tag: $FASTAPI_POLICY_FSPF_TAG
environment:
DB_HOST: $DB_HOST
DB_USER: $DB_USER
......@@ -75,7 +78,7 @@ secrets:
import:
session: $MEMCACHED_SESSION
secret: MEMCACHED_CA_CERT
# specific for fastapi - nginx tls
# specific for fastapi - nginx tls
- name: fastapi-key # automatically generate FASTAPI server certificate
kind: private-key
- name: fastapi # automatically generate FASTAPI server certificate
......
......@@ -21,9 +21,9 @@ services:
command: ["nginx", "-g", "master_process off; daemon off;"]
mrenclaves: ["$MRENCLAVE_NGINX"]
pwd: /
#fspf_path: /fspf.pb
#fspf_key: $NGINX_POLICY_FSPF_KEY
#fspf_tag: $NGINX_POLICY_FSPF_TAG
fspf_path: /fspf.pb
fspf_key: $NGINX_POLICY_FSPF_KEY
fspf_tag: $NGINX_POLICY_FSPF_TAG
images:
- name: nginx_image
......@@ -36,14 +36,12 @@ images:
- path: /etc/nginx/fastapi-client.key
content: $$SCONE::FASTAPI_CLIENT_CERT.key$$
# specific for nginx - client tls
- path: /etc/nginx/server-ca.crt
content: $$SCONE::SERVER_CA_CERT.chain$$
- path: /etc/nginx/server.crt
content: $$SCONE::server.crt$$
- path: /etc/nginx/server.key
content: $$SCONE::server.key$$
# Import client credentials from DB session.
# Import client credentials from FastAPI session.
secrets:
# nginx - fastapi tls
- name: FASTAPI_CLIENT_CERT
......@@ -64,10 +62,6 @@ secrets:
dns:
- $NGINX_HOST
- secure-doc-management
- name: SERVER_CLIENT_KEY
kind: private-key
export:
- session: $NGINX_SESSION
- name: SERVER_CA_KEY # export session CA certificate as SERVER CA certificate
kind: private-key
- name: SERVER_CA_CERT # export session CA certificate as SERVER CA certificate
......
......@@ -69,7 +69,7 @@ We store the documents and user authentication information in a secure MariaDB,
## Secure Memcached Rate Limiter
To ensure that our MariaDB is not overloaded by excess requests, we limit requests per user using a Memcached service. We thereby ensure that a user can make at most 10 requests per minute. If the user's requests exceed that limit, we do not serve requests to their corresponding IP address for the remainder of the minute. We achieve this limiter by storing the user's IP and their number of requests in a key/value pair in the Memcached service in our Python program: `mc_client.set(key=client_ip, value=1, expire=60)`. Upon a request, we increment the key/value pair using Memcached's `incr` command: `mc_client.incr(key=client_ip, value=1)`. If this value exceeds 10, we do not serve the requests. The key value pair expires after 60 seconds.
To ensure that our MariaDB is not overloaded by excess requests, we limit requests per user using a Memcached service. We thereby ensure that a user can make at most 10 requests per minute. If the user's requests exceed that limit, we do not serve requests to their corresponding IP address for the remainder of the minute. We achieve this limiter by storing the user's IP and their number of requests in a key/value pair in the Memcached service in our [Python program](https://scone.cf/enterJazz/secure-doc-management/-/blob/master/fastapi-setup/rest_api.py): `mc_client.set(key=client_ip, value=1, expire=60)`. Upon a request, we increment the key/value pair using Memcached's `incr` command: `mc_client.incr(key=client_ip, value=1)`. If this value exceeds 10, we do not serve the requests. The key value pair expires after 60 seconds.
As we attribute the IP of a user to Personally Identifiable Information (PII), we have to protect this data. We ensure this protection by running the Memcached inside of an enclave.
......@@ -79,3 +79,183 @@ As we attribute the IP of a user to Personally Identifiable Information (PII), w
We employ an NGINX to be the main API of the service, and to ensure secure communication over the wire with TLS. The NGINX requires users to send their requests over TLS, as we specify in its [configuration](https://scone.cf/enterJazz/secure-doc-management/-/blob/master/nginx-setup/nginx.conf). The NGINX then forwards such requests to the FastAPI service, also using TLS. It thereby specifies the correct FastAPI port, thus enabling the user to send the service requests without having to specify the port themselves.
As the NGINX thereby receives the sensitive information of the documents, we run the NGINX proxy server in an enclave as well.
## TLS Certificates
We must secure the communication between 1) the application's services and between 2) the user and the application. Therefore, we need to issue and provision multiple certificates:
- MariaDB: requires server certificates
- Memcached: requires server certificates
- FastAPI: requires server certificates and client certificates for the Memcached and MariaDB for client verification
- NGINX: requires server certificates, whereby the certification authority (CA) certificate must be accessible to users, and client certificates for the FastAPI for client verification
We provision these certificates using [SCONE policies](https://sconedocs.github.io/CAS_session_lang_0_3/). We now illustrate the use of the policies for certificate provisioning by inspecting the [NGINX policy](https://scone.cf/enterJazz/secure-doc-management/-/blob/master/policy-setup/nginx_session.yml).
```yaml
secrets:
# nginx - fastapi tls
- name: FASTAPI_CLIENT_CERT
import:
session: $FASTAPI_SESSION
secret: FASTAPI_CLIENT_CERT
- name: FASTAPI_CA_CERT
import:
session: $FASTAPI_SESSION
secret: FASTAPI_CA_CERT
# specific for nginx - client tls
- name: server-key # automatically generate SERVER server certificate
kind: private-key
- name: server # automatically generate SERVER server certificate
private_key: server-key
issuer: SERVER_CA_CERT
kind: x509
dns:
- $NGINX_HOST
- secure-doc-management
- name: SERVER_CA_KEY # export session CA certificate as SERVER CA certificate
kind: private-key
- name: SERVER_CA_CERT # export session CA certificate as SERVER CA certificate
kind: x509-ca
common_name: SERVER_CA
private_key: SERVER_CA_KEY
export_public: true
```
In the first section, `# nginx - fastapi tls`, the NGINX session imports the client and the server CA certificates from the FastAPI session. It thereby uses the CA certificate to identify the FastAPI service, and identifies itself to the service using the client certificates.
In the second section, `# (...) nginx - client tls`, we issue server certificates for the NGINX. For the NGINX Server CA certificate, we set `export_public: true`. This settings allows users to extract the CA certificate corresponding to this policy, thus enabling them to verify the NGINX server.
To make the certificates available to the NGINX service, we inject the certificates into the NGINX file system. We specify this injection in the [NGINX policy](https://scone.cf/enterJazz/secure-doc-management/-/blob/master/policy-setup/nginx_session.yml) using the previous SCONE policy secrets as follows:
```yaml
images:
- name: nginx_image
injection_files:
# nginx - fastapi tls
- path: /etc/nginx/fastapi-ca.crt
content: $$SCONE::FASTAPI_CA_CERT.chain$$
- path: /etc/nginx/fastapi-client.crt
content: $$SCONE::FASTAPI_CLIENT_CERT.crt$$
- path: /etc/nginx/fastapi-client.key
content: $$SCONE::FASTAPI_CLIENT_CERT.key$$
# specific for nginx - client tls
- path: /etc/nginx/server.crt
content: $$SCONE::server.crt$$
- path: /etc/nginx/server.key
content: $$SCONE::server.key$$
```
The NGINX can then access these injected files as normal files, e.g., in its configuration:
```conf
events {}
http {
server {
listen 443 ssl;
server_name secure-doc-management-nginx-scone;
ssl_certificate /etc/nginx/server.crt;
ssl_certificate_key /etc/nginx/server.key;
location / {
proxy_pass https://secure-doc-management-fastapi-scone:8000;
proxy_ssl_certificate /etc/nginx/fastapi-client.crt;
proxy_ssl_certificate_key /etc/nginx/fastapi-client.key;
proxy_ssl_trusted_certificate /etc/nginx/fastapi-ca.crt;
proxy_ssl_verify on;
proxy_ssl_session_reuse on;
}
}
}
```
## TLS-Based Mutual Attestation
As we observed in the previous section, we encrypt the communication between the NGINX and the FastAPI using TLS, enabled by SCONE policies. The NGINX and FastAPI policies thereby export the necessary certificates to each other by referencing each other in their policies. They thereby *attest* each other. They achieve this attestation by verifying the policies that they reference in their own policy. Furthermore, they check that the corresponding service satisfies all requirements specified in the service's policy.
We can easily enforce mutual attestation using TLS client authentication. We illustrate this attestation with the [FastAPI's policy](https://scone.cf/enterJazz/secure-doc-management/-/blob/master/policy-setup/fastapi_session.yml), which ensures TLS-based attestation between itself and the NGINX service. This FastAPI policy generates a FastAPI CA certificate (`FASTAPI_CA_CERT`) and a FastAPI server certificate (`fastapi`) as well as a corresponding FastAPI client certificate (`FASTAPI_CLIENT_CERT`) and client key (`FASTAPI_CLIENT_KEY`). The policy exports this certificate and private key to the NGINX policy.
```yaml
secrets:
...
# specific for fastapi - nginx tls
- name: fastapi-key # automatically generate FASTAPI server certificate
kind: private-key
- name: fastapi # automatically generate FASTAPI server certificate
private_key: fastapi-key
issuer: FASTAPI_CA_CERT
kind: x509
dns:
- $FASTAPI_HOST
- name: FASTAPI_CLIENT_KEY
kind: private-key
export:
- session: $NGINX_SESSION
- name: FASTAPI_CLIENT_CERT # automatically generate client certificate
private_key: FASTAPI_CLIENT_KEY
issuer: FASTAPI_CA_CERT
common_name: FASTAPI_CLIENT_CERT
kind: x509
export:
- session: $NGINX_SESSION # export client cert/key to upload session
- name: FASTAPI_CA_KEY # export session CA certificate as FASTAPI CA certificate
kind: private-key
- name: FASTAPI_CA_CERT # export session CA certificate as FASTAPI CA certificate
kind: x509-ca
common_name: FASTAPI_CA
private_key: FASTAPI_CA_KEY
export:
- session: $NGINX_SESSION # export the session CA certificate to upload session
```
We thereby replace `$NGINX_SESSION` with the policy name of the NGINX. For increased security, we can also specify the corresponding [session hash](https://sconedocs.github.io/CAS_session_lang_0_3/#session-description-hash). In this scenario, the policies are on the same [SCONE CAS](helm_cas.md). In more complex cases, the policies can be stored on different [SCONE CAS](helm_cas.md).
The NGINX can then import the FastAPI CA certificate, client certificate and private key, as we saw before:
```yaml
secrets:
# nginx - fastapi tls
- name: FASTAPI_CLIENT_CERT
import:
session: $FASTAPI_SESSION
secret: FASTAPI_CLIENT_CERT
- name: FASTAPI_CA_CERT
import:
session: $FASTAPI_SESSION
secret: FASTAPI_CA_CERT
# specific for nginx - client tls
- name: server-key # automatically generate SERVER server certificate
kind: private-key
- name: server # automatically generate SERVER server certificate
private_key: server-key
issuer: SERVER_CA_CERT
kind: x509
dns:
- $NGINX_HOST
- secure-doc-management
- name: SERVER_CA_KEY # export session CA certificate as SERVER CA certificate
kind: private-key
- name: SERVER_CA_CERT # export session CA certificate as SERVER CA certificate
kind: x509-ca
common_name: SERVER_CA
private_key: SERVER_CA_KEY
export_public: true
```
`$FASTAPI_SESSION` is the exporting policy of the FastAPI. The NGINX can then use these exported secrets, as we also saw before:
```yaml
images:
- name: nginx_image
injection_files:
# nginx - fastapi tls
- path: /etc/nginx/fastapi-ca.crt
content: $$SCONE::FASTAPI_CA_CERT.chain$$
- path: /etc/nginx/fastapi-client.crt
content: $$SCONE::FASTAPI_CLIENT_CERT.crt$$
- path: /etc/nginx/fastapi-client.key
content: $$SCONE::FASTAPI_CLIENT_CERT.key$$
```
To ensure that the SCONE CAS supplying these policies is genuine, we typically attest the SCONE CAS before uploading any policies using the [SCONE CAS CLI](https://sconedocs.github.io/aks/flask_demo/helm_cas/#attesting-scone-cas).
......@@ -9,7 +9,7 @@ set -o nounset
# Catch the error in case mysqldump fails (but gzip succeeds) in `mysqldump |gzip`
set -o pipefail
# Turn on traces, useful while debugging but commented out by default
#set -o xtrace
set -o xtrace
export IMAGE_PULL_SECRET=${IMAGE_PULL_SECRET:-enterjazz-gitlab-scontain}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment