Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial backend architecture diagram #4

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Potato Farmer

Manages `potato_field` and `potato_plants`. Main way to administrate containers.

## Setup

### Dependencies

There are several dependencies required for the development and deployment of this project.
The first is Docker Engine and Docker Compose. The second is Python3.
The following list links to the installation instructions for each of these:

* [Docker Engine installation instructions.](https://docs.docker.com/engine/install/)
* [Docker Compose installation instructions.](https://docs.docker.com/compose/install/)
* [Python3 installation instructions.](https://www.python.org/downloads/)

### Sub-repository management

The tool `setup.py` can be used to clone (or symlink) project repositories for deployment.

For instance, the following command will clone the `potato_plant_dashboard` and `potato_plant_missions`
repositories (hosted in the BourbonWarfare organization) into the project root:
```bash
python3 setup.py add plant_dashboard plant_missions
```
The resulting repositories would then be cloned into `potato_field/` and are symlinked into the
`potato/` directory.

<!-- TODO: add demonstration of `link` command. -->
1 change: 1 addition & 0 deletions docs/backend/diagrams/backend.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<mxfile host="Electron" modified="2023-01-22T04:34:53.260Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/20.7.4 Chrome/106.0.5249.199 Electron/21.3.3 Safari/537.36" etag="tK5KOWt1-LT74RKj3L4c" version="20.7.4" type="device"><diagram id="63_J9xoC3GJqVzZ7b3mH" name="Page-1">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</diagram></mxfile>
11 changes: 11 additions & 0 deletions docs/backend/diagrams/backend.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=5,IE=9" ><![endif]-->
<!DOCTYPE html>
<html>
<head>
<title>backend-architecture-diagram</title>
<meta charset="utf-8"/>
</head>
<body><div class="mxgraph" style="max-width:100%;border:1px solid transparent;" data-mxgraph="{&quot;highlight&quot;:&quot;#0000ff&quot;,&quot;nav&quot;:true,&quot;resize&quot;:true,&quot;toolbar&quot;:&quot;zoom layers tags lightbox&quot;,&quot;edit&quot;:&quot;_blank&quot;,&quot;xml&quot;:&quot;&lt;mxfile host=\&quot;Electron\&quot; modified=\&quot;2023-01-22T04:39:04.042Z\&quot; agent=\&quot;5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/20.7.4 Chrome/106.0.5249.199 Electron/21.3.3 Safari/537.36\&quot; etag=\&quot;J_V41G_Kcoi2i2imc3jk\&quot; version=\&quot;20.7.4\&quot; type=\&quot;device\&quot;&gt;&lt;diagram id=\&quot;63_J9xoC3GJqVzZ7b3mH\&quot; name=\&quot;Page-1\&quot;&gt;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&lt;/diagram&gt;&lt;/mxfile&gt;&quot;}"></div>
<script type="text/javascript" src="https://viewer.diagrams.net/js/viewer-static.min.js"></script>
</body>
</html>
Binary file added docs/backend/diagrams/backend.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
154 changes: 154 additions & 0 deletions docs/threat-model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# `potato_farmer` Threat Model

## Project Description

This project manages `potato_field` and `potato_plants`. It's the main way to administrate
containers; services that run in the backend to support the main application.

### User System

There will be a user system with a hierarchy of users, ranging from administrators to normal users
that have restricted access to applications. A user should be uniquely identified and should not
be able to pose as another user.

### Backend Services

There will be a number of backend services that expose an API for other backend applications to
interact with. These backend services should **not** be exposed to the outside world; rather,
this should be managed by the API Gateway.

### API Gateway

The API Gateway takes requests from the outside world -- that is, from users and outside automated
services -- and collates data and operations from one or more backend services to satisfy the
request. The API Gateway should generally be the **only** way for users to access applications.

## Threats

### (1) User Impersonation

As users should be uniquely identified, it would violate the assumptions of our application if a
user was able to successfully pose as another user. This would possibly permit a user to access
another user's information, ruin their reputation in community spaces/applications, or utilize
privileges that they should not have access to, as described in (2).

### (2) Privilege Escalation

As there will be a hierarchy of users with varying capabilities, it should not be possible for a
user to gain additional privileges without them being granted by an administrator. Violation of
this assumption would allow ordinary users to take advantage of privileges they should not have
access to, potentially wreaking havoc regardless of malicious intent.

### (3) Direct Access to Backend Services

Backend services should not be directly accessible. Violation of this principle could permit actors
to access APIs they should not have access to, potentially wreaking havoc on internal state or
exposing data that should remain private to them.

### (4) API Gateway Overloading

As the API Gateway is the main way for users to interact with applications, it serves as a single
point of failure for the entire application. By overloading the API Gateway, malicious actors (or
just a sudden spike of traffic) can disrupt the availability of the application for all users.

### (5) Network Eavesdropping

There may be actors that are listening in on communications between our users or between services
in our application. Through eavesdropping on network communications, malicious actors could learn
private user/system/operational data that they should not have access to. Further, they may be able
to construct spoofed requests for abuse in conjunction with Threat (3).

## Defense Mechanisms

### (1, 2) User Authentication

To protect against user impersonation, the application will utilize mechanisms of user authentication
to validate the user's identity prior to allowing access to any privileged operations or data (including
operations or data tied to user identity).

#### Password Authentication

Upon user creation, users will select a password to use for authentication. If possible, we should
include a password strength meter to help users choose a strong password. We will impose several
requirements to ensure the password is not trivially bruteforceable.

1. Minimum of 12 characters; maximum of 60 characters
2. Includes at least one number
3. Includes at least one uppercase and lowercase alphabetic character
4. Includes at least one non-alphabetic character (symbol)

These passwords will be stored in a User Authentication service. The modern algorithm Argon2id is
considering the most secure and correct to use in modern applications, but is resource-heavy. All
passwords should be salted, but Argon2id should handle this itself. Password hashes should be
compared using only safe functions that have been vetted by security experts.

#### Two Factor Authentication (2FA)

As user passwords may be shared between multiple services, may be bruteforceable, may be leaked
through a variety of means, etc., our application will utilize 2FA to further validate user
identities. This 2FA mechanism will be opt-in and will utilize email to send a user a six-digit
one-time code to be validated after username/password validation succeeds. Bypassing this mechanism
requires malicious actors to also have access to the user's email.

### (1, 2) User Sessions

It is not practical to require users to authenticate for every request. This presents a poor UX
and is expensive for our backend services. To alleviate this pressure, we will implement user
sessions to permit users to authenticate once and continue submitting requests for a time without
requiring authentication again.

User sessions will be implemented by a `SessionID` that is a 128-bit string, the length chosen
to harden `SessionID`s against bruteforce attacks. These will be randomly generated with
cryptographically strong randomness. `SessionID`s will be stored in a Redis memory store alongside
a `UserID` and a session timeout. Sessions will have an idle timeout of 1 hour and an absolute
timeout of 1 day after authentication. We could consider introducing a renewal timeout as well,
but this would add additional complexity.

Users will receive their 128-bit `SessionID` after successful user authentication. This will have
to be sent with every privileged request in a manner specified by the application API. The API
Gateway would check the Redis memory store to validate the `SessionID` before serving the request.
Failure to validate the `SessionID` would result in a failure which would be communicated to the user.

Note that as `SessionID`s will be sent as a HTTP Cookie, it is important to properly protect against
CSRF attacks with the proper use of CSRF tokens.

### (3) Internal Docker Network

Backend services will operate within an internal Docker network that would not have exposed ports
to the outside world. Only the API Gateway will be publicly accessible. This should prevent
outside access of restricted backend services and force users to use the API Gateway to interact
with applications.

To clarify, the API Gateway will also be containerized and will access backend service APIs through
the internal Docker network. Docker containers within the internal network will be assumed to be
trustworthy and can talk at will.

### (4) Rate Limiting

As the application continues to grow in scale, users will be rate limited and the API Gateway will
not serve requests beyond the rate limit. Rate limiting should be stricter for non-authenticated
endpoints. Users who repeatedly attempt to violate rate limiting rules should be restricted from
accessing authenticated endpoints. Anonymous actors who repeatedly attempt to violate rate limiting
rules may have their source IP banned (note that this may be problematic if many machines share a
NAT).

We may consider implementing our own rate limiting mechanisms, or using off-the-shelf solutions.
This mechanism will also likely depend on the implementation of our API Gateway.

### (5) TLS/SSL/DTLS

All user-application communications and backend-service communications will utilize TLS/SSL for TCP
connections to ensure that private user/system/operational data is not leaked to external eavesdroppers.
Thanks to Mechanism (3), it should not be possible for eavesdroppers to have access to private
backend service communications, but these should still be encrypted as much as possible regardless
to ensure a layered defense.

For UDP communications, we can consider a variety of integrity mechanisms. DTLS has been advertised
as an integrity mechanism analogous to TLS for TCP, but the practical usage of this protocol may
need more investigation.

## Appendix

Consult the [Web Security Confluence Page](https://bourbonwarfare.atlassian.net/wiki/spaces/~62fd97fc88b05653fa7d6975/pages/557057/Web+Security)
for a list of some of the sources consulted in the making of this document, as well as a list of
resources on how to implement some of these security mechanisms correctly.
Loading