Skip to content

Commit

Permalink
Improve README
Browse files Browse the repository at this point in the history
  • Loading branch information
parisk committed Apr 13, 2018
1 parent 315f891 commit 090069e
Showing 1 changed file with 73 additions and 17 deletions.
90 changes: 73 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
# Sec - Simple library for using secrets in Python applications
# Sec - Tiny Python library for using secrets

[![Build Status](https://travis-ci.org/sourcelair/sec.svg?branch=master)](https://travis-ci.org/sourcelair/sec)

Sec is a simple library for using secrets in Python applications. Simple to its core, Sec exposes just **one function** and offers **no configurations options**.
Sec is a tiny Python library for using secrets. Simple to its core, Sec exposes just **one function** and offers **no configurations options**.

---

If you are developing web applications, then by most chances your application uses some sort of "secret" information (e.g. database passwords, API keys etc.) which hopefully 🙏 is not kept into the code base.

Since this kind of information is not kept in the database, it resides in an external place like a file (e.g. `/run/secrets/aws-key`) or an environment variable (e.g. `DATABASE_URL`).

All Sec does is provide a single, unique interface for accessing these information from a Python application.

## Installation

To install `sec` use Pipenv to add it to the dependencies of your project
You can install `sec` with Pipenv:

```
pipenv install sec
Expand All @@ -27,36 +35,84 @@ The `load` method of Sec attempts to load the contents of a secret, based on a g
3. Load the content of the environment variable `{name}` (`name` is uppercased here)
4. Return the value of the `fallback` argument if provided, or `None`

## Examples
## Quick Start Example

First, let's create some secret files

### Loading a secret from `/run/secrets`
```shell
$ echo "mystiko" > /run/secrets/supersecret
$ export MYSECRET_FILE=/run/secrets/supersecret
$ export ANOTHER_SECRET=hello
```

Let's assume that the file `/run/secrets/database-password` exists and its content is `123`.
Next, let's open up the Python interpreter and load these secrets in our application.

```python
import sec

sec.load('database-password') # This will return `123`
>>> import sec
>>> sec.load('mystiko')
'supersecret'
>>> sec.load('mysecret')
'supersecret'
>>> sec.load('another_secret')
'hello'
```

### Loading a secret based on an environment variable hint
## Use Cases

### Docker Swarm Secrets

[Docker Secrets](https://docs.docker.com/engine/swarm/secrets/) lets services running on Docker Swarm get exclusive access to secret information that are encrypted at rest.

Let's assume that the environment variable `AWS_KEY_FILE` exists, its content is `/etc/app/my_aws_key` and that the content of `/etc/app/my_aws_key` is `wow`.
Although this feature is amazing, it cannot be used outside of Docker Swarm (e.g. in Docker on your local machine) so developers tend to create hacks and workarounds around this issue.

This is where `sec` comes into play. The following application code will work the same in production with Docker Secrets and in development with environment variables instead.

```python
import sec

sec.load('aws_key') # This will return `wow`
# The following line will work the same in development and production
database_url = sec.load('database_url')
```

### Loading a secret based on an environment variable
Below you can see the corresponding Docker files that we set up to run the above application.

Let's assume that the environment variable `DATABASE_URL` exists and its content is `sqlite:///mnt/db.sqlite`.
#### `docker-compose.yml`

```python
import sec
```yaml
version: "3.6"

services:
web:
image: company/app
secrets:
- database-url

secrets:
settings:
external:
name: database-url
```
#### `docker-compose.override.yml`

```yaml
version: "3.6"
services:
web:
build: .
volumes:
- .:/usr/src/app
environment:
DATABASE_URL: postgresql://user:password@postgres
postgres:
image: postgres:latest
sec.load('database_url') # This will return `sqlite:///mnt/db.sqlite`
secrets:
settings:
external:
name: database-url
```

## License
Expand Down

0 comments on commit 090069e

Please sign in to comment.