Managing Policies

The example in this section shows how to encrypt a file using a key stored in the Anjuna Policy Manager. For demonstration, you will run two simple Python 3 scripts that receive a password from the user, save it into an encrypted file, and then read the encrypted file and print the decrypted contents.

First, create a default manifest:

$ anjuna-sgxrun --setup

Start the Anjuna Policy Manager Broker in a different directory (replace anjuna-broker with a directory of your choice):

$ mkdir anjuna-broker
$ cd anjuna-broker
$ anjuna-sgxrun apmbroker &>/dev/null &
The Anjuna Policy Manager Broker must be started in the Anjuna SGX Runtime to ensure that its communication with the main application and the Anjuna Policy Manager is fully protected. In addition, the Anjuna Policy Manager Broker will only accept communicating with other applications running in the Anjuna SGX Runtime that have been signed with the same signing key. This happens automatically when using the anjuna-sgxrun tool, which signs enclaves with a key specified by the SGX_SIGNER_KEY environment variable.

Start the Anjuna Policy Manager:

$ anjuna-policy-manager server start --dev

Anjuna Policy Manager server is up and running
- Address: https://apm-server.test:8201
- Certificate: /opt/anjuna/anjuna-policy-manager/dev/conf/https/cert/cert.pem

Add the following entries to your application’s manifest to connect to the Anjuna Policy Manager Server:

policy_manager:
  socket: apm-broker
  url: https://apm-server.test:8201
  ca_cert: |
    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----

Copy the manifest field policy_manager printed by starting the Anjuna Policy Manager into the manifest template (manifest.template.yaml).

Next, edit the manifest template again, but this time add entries that specify a file that is encrypted automatically with a secret stored remotely in the Anjuna Policy Manager. Edit manifest.template.yaml and add the following lines to it:

keys:
  - id: password_encryption_key
    source: key_server
    uri: anjuna://encryption_keys/password
    engine: anjuna

encrypted_files:
  - path: secret_password.encrypted
    key: password_encryption_key

The keys entry specifies a remote key with the ID of password_encryption_key, stored remotely inside the Anjuna Policy Manager with the path anjuna/encryption_keys/password.

The encrypted_files entry specifies that the file secret_password.encrypted should be encrypted using the key password_encryption_key (the previously defined remote key).

Now that the manifest template is set up, you need to compile it to create the manifest file and to create a signature file:

$ anjuna-compile-manifest $(which python3)
$ anjuna-sign $(which python3)

To add a secret to the Anjuna Policy Manager and attach it to the enclave, you will use the tool anjuna-policy-manager.

Before using anjuna-policy-manager to manage secrets, set up two environment variables that tell anjuna-policy-manager how to connect to the running Anjuna Policy Manager, and which CA certificate to use to set up the TLS connection to Anjuna Policy Manager:

$ export ANJUNA_ADDR="https://apm-server.test:8201"
$ export ANJUNA_CACERT="/opt/anjuna/anjuna-policy-manager/dev/conf/https/cert/cert.pem"

Execute anjuna-policy-manager to create a new secret in the Anjuna Policy Manager:

$ anjuna-policy-manager secret create --engine-path anjuna encryption_keys/password --value SECRETENCRYPTION

After the secret is created inside the Anjuna Policy Manager, attach it to an enclave in order to grant permissions for that enclave to read the secret:

$ anjuna-policy-manager authorize enclave --engine-path anjuna encryption_keys/password --sig-file python3.sig

With the secret configured and attached to the enclave, you can now execute an application that uses that secret to encrypt a file. You will execute two Python scripts, one that receives a password from the user and saves it to the encrypted file, and one that reads the encrypted file and prints its decrypted contents to stdout. The Anjuna Runtime automatically encrypts the file when writing data to it and automatically decrypts the data when reading it.

Execute the first Python script that receives a password and saves it to the file using the Anjuna Runtime:

$ anjuna-sgxrun python3 -c "password = input('Please enter a password: '); open('secret_password.encrypted', 'w').write(password)"

This command generates and encrypts the file secret_password.encrypted. You can see that the file has the Anjuna header for encrypted files by running the following command:

$ hexdump -C secret_password.encrypted
00000000  41 4e 4a 55 4e 41 46 53  01 00 04 01 22 85 3a e1  |ANJUNAFS....".:.|
00000010  a1 2b 9b 63 34 b3 79 f0  4c 13 ca 90 0a 75 0c 9b  |.+.c4.y.L....u..|
00000020  21 f6 b0 c3 43 ae 1e 60  4e a0 92 d8 29 16 31 90  |!...C..`N...).1.|

Now, execute another Python script that reads and prints the contents of the file inside the Anjuna Runtime. The Anjuna Runtime automatically decrypts the contents of the file.

$ anjuna-sgxrun python3 -c "password = open('secret_password.encrypted', 'r').read(); print('The password is: ' + password)"