diff --git a/docs/.nojekyll b/docs/.nojekyll
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 000000000..e38a66851
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,68 @@
+# SOPS: Secrets OPerationS
+
+`sops` is a secrets management solution and editor of encrypted files that
+supports a variety of file formats and encryption providers.
+
+Here is a quick demo of `sops` in action:
+
+
+
+
+A more in-depth overview is available as part of Julien Vehent's Securing
+DevOps Show & Tell:
+
+
+
+If you want to use SOPS as a Go library, take a look at the [decrypt
+package](https://godoc.org/go.mozilla.org/sops/decrypt).
+
+**Questions?** Ping `ulfr` and `autrilla` in `#security` on
+[`irc.mozilla.org`](https://wiki.mozilla.org/IRC) (you can use a web client
+like [mibbit](https://chat.mibbit.com)).
+
+**What happened to Python SOPS?** We rewrote `sops` in Go to solve a number of
+deployment issues, but the Python branch still exists under `python-sops`. We
+will keep maintaining it for a while, and you can still `pip install sops`, but
+we strongly recommend you use the Go version instead.
+
+Backward compatibility
+----------------------
+
+We strive to make as few backwards-incompatible changes as possible to the
+`sops` command line tool. We follow [Semantic Versioning](https://semver.org/),
+so in the rare occurence that we break compatibility on the CLI, you'll know.
+
+The file format will always be backwards compatible: this means that newer
+versions of SOPS will be able to load files created with older versions of
+SOPS.
+
+Security
+--------
+
+Please report security issues to jvehent at mozilla dot com, or by using one of
+the contact method available on keybase: https://keybase.io/jvehent
+
+License
+-------
+
+Mozilla Public License Version 2.0
+
+Authors
+-------
+
+The core team is composed of:
+
+* Adrian Utrilla [@autrilla](https://github.com/autrilla)
+* Julien Vehent [@jvehent](https://github.com/jvehent)
+* AJ Banhken [@ajvb](https://github.com/ajvb)
+
+And a whole bunch of [contributors](https://github.com/mozilla/sops/graphs/contributors).
+
+Credits
+-------
+
+SOPS was inspired by [hiera-eyaml](https://github.com/TomPoulton/hiera-eyaml),
+[credstash](https://github.com/LuminalOSS/credstash),
+[sneaker](https://github.com/codahale/sneaker), [password
+store](http://www.passwordstore.org/), and too many years managing PGP
+encrypted files by hand.
diff --git a/docs/_sidebar.md b/docs/_sidebar.md
new file mode 100644
index 000000000..1a32ec836
--- /dev/null
+++ b/docs/_sidebar.md
@@ -0,0 +1,32 @@
+
+
+* [SOPS](/)
+* [Installation](installation.md)
+* [Quick Start](quick_start.md)
+* Usage
+ * [Encrypting files](usage/encrypting_files.md)
+ * [Decrypting files](usage/decrypting_files.md)
+ * [Editing files](usage/editing_files.md)
+ * [Git differ](usage/git_differ.md)
+ * [Key rotation](usage/key_rotation.md)
+ * [Key groups](usage/key_groups.md)
+ * [Publishing files](usage/publishing_files.md)
+ * [Key service](usage/key_service.md)
+ * [Auditing](usage/auditing.md)
+ * [Partial file encryption](usage/partial_file_encryption.md)
+* [The `.sops.yaml` configuration file](sops_yaml_config_file.md)
+* Encryption providers (master key types)
+ * [AWS KMS](encryption_providers/aws_kms.md)
+ * [GCP KMS](encryption_providers/gcp_kms.md)
+ * [Azure KeyVault](encryption_providers/azure_keyvault.md)
+ * [PGP](encryption_providers/pgp.md)
+* Storage formats
+ * [YAML](storage_formats/yaml.md)
+ * [JSON](storage_formats/json.md)
+ * [.env](storage_formats/dotenv.md)
+ * [INI](storage_formats/ini.md)
+ * [Arbitrary (binary) files](storage_formats/binary.md)
+* Internals
+ * [Encryption protocol](internals/encryption_protocol.md)
+* [Comparison with other tools](comparison_with_other_tools.md)
+
diff --git a/docs/index.html b/docs/index.html
new file mode 100644
index 000000000..0215c051e
--- /dev/null
+++ b/docs/index.html
@@ -0,0 +1,24 @@
+
+
+
+
+ SOPS
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/installation.md b/docs/installation.md
new file mode 100644
index 000000000..80488a792
--- /dev/null
+++ b/docs/installation.md
@@ -0,0 +1,23 @@
+Installation
+============
+
+Stable release
+--------------
+
+Binaries and packages of the latest stable release are available
+[here](https://github.com/mozilla/sops/releases).
+
+Development branch
+------------------
+
+For the adventurous, unstable features are available in the develop branch, which you can install from source:
+
+```bash
+$ go get -u go.mozilla.org/sops/cmd/sops
+$ cd $GOPATH/src/go.mozilla.org/sops/
+$ git checkout develop
+$ make install
+```
+
+Requires Go 1.12 or newer. If you don't have Go installed, refer to the
+[official Go documentation](https://golang.org/doc/install).
diff --git a/docs/quick_start.md b/docs/quick_start.md
new file mode 100644
index 000000000..16c6dd078
--- /dev/null
+++ b/docs/quick_start.md
@@ -0,0 +1,121 @@
+Quick Start
+-----------
+
+Now that you've have the `sops` binary [installed](installation.md), you should
+be able to run the binary:
+
+```bash
+$ sops -v
+sops 3.3.1 (latest)
+```
+
+For simplicity, we will use PGP as an encryption provider. We assume you
+already have a PGP key, but if you don't, [Github's
+documentation](https://help.github.com/en/articles/generating-a-new-gpg-key)
+explains how you can create one. Take note of your public key's fingerprint, as
+you'll need it later.
+
+?> Tip: you can find your key's fingerprint by running `gpg --list-keys`. The
+fingerprint is a long string (typically 40 characters) of hexadecimal
+characters.
+
+In my case, the PGP fingerprint is `1022470DE3F0BC54BC6AB62DE05550BC07FB1A0A`,
+so I will be using that for the rest of the quick start. Replace it with your
+own fingerprint whenever I use it. This is used by the SOPS project for
+testing infrastructure. If you struggle generating your own key, you can use
+this fingerprint as well, as `sops` will try to download the key from the
+Internet if it is not available locally.
+
+!> If you use the SOPS testing infrastructure key, you won't be able to decrypt
+files unless you also download and import the private key. It is available
+[here](../pgp/sops_functional_tests_key.asc). Download it and then import it
+with `gpg --import sops_functional_tests_key.asc`.
+
+Now that we have our PGP key set up, let's create a new SOPS encrypted file:
+
+```bash
+$ sops --pgp 1022470DE3F0BC54BC6AB62DE05550BC07FB1A0A quickstart.yaml
+```
+
+Upon running this, you should be taken to an editor and be shown an example
+file:
+
+```yaml
+hello: Welcome to SOPS! Edit this file as you please!
+example_key: example_value
+# Example comment
+example_array:
+- example_value1
+- example_value2
+example_number: 1234.5679
+example_booleans:
+- true
+- false
+```
+
+Make some edits to the file, for example, add some data to the end of the
+file, so it looks like this:
+
+```yaml
+hello: Welcome to SOPS! Edit this file as you please!
+example_key: example_value
+# Example comment
+example_array:
+- example_value1
+- example_value2
+example_number: 1234.5679
+example_booleans:
+- true
+- false
+some_more_data:
+ hello: world
+```
+
+Save the file. Let's see what it looks like:
+
+```bash
+$ cat quickstart.yaml
+```
+```yaml
+hello: ENC[AES256_GCM,data:r8pcvLb9EZyZFdy/Q1S0lI6JNxsZuf1QM9ZUw7n/A8QkBf1e9B7yOcI1BbzjcQ==,iv:mI5g/blnelhbr75h/yhxyrExPDPaEProWyh9Q0OItv4=,tag:w8ixFTZkRtc+OVSyZOPlrw==,type:str]
+example_key: ENC[AES256_GCM,data:87zFG19/7ooxavTFHA==,iv:E3po1Pf4vvqfOaZtfNMPA6BnUCxs1FHu95AVVv3zbrc=,tag:gM7hn6jlXn9QKYPalUkL1g==,type:str]
+#ENC[AES256_GCM,data:eJZ9g+Ikh1ijDuwADlbksg==,iv:k8yO0gFoFkpWX/dTZ5IsNvh0ld/cxSkiE0kgyVegZs8=,tag:7qB7CANMs4ZndzfAqrmNiA==,type:comment]
+example_array:
+- ENC[AES256_GCM,data:rDGwfQzcPB7MWWj+ks8=,iv:LEKN7Yq2KXpukQJcEFG9VJAJ4vSs+2r3QlljHYbsIuA=,tag:JG4WyZOqUzzPkAlPAo/bnQ==,type:str]
+- ENC[AES256_GCM,data:TdLQadOzpSTZ4dMqSG0=,iv:AUE5L4VMy+N6tw/aeyZhQcckFxjQgTI3UyI6p6o2HOE=,tag:AAh+WQpO/jSvGvbEH5/QPw==,type:str]
+example_number: ENC[AES256_GCM,data:vZkNkTjce/tC,iv:8FlC3NF+AJpHJ6JGtl1oMgw+8btxsKlZqCbXlhQ60Ss=,tag:2AaHYIC7OSYU27JxQTlhXQ==,type:float]
+example_booleans:
+- ENC[AES256_GCM,data:4oWlWw==,iv:YxEiZ+uweb8rLZBY5nvtt/8LpCl9q+TTCJEyyu6gzhE=,tag:pcZl3mh0y+Uyo/bRePXohg==,type:bool]
+- ENC[AES256_GCM,data:FBeNQA4=,iv:dQOSHy8Tgs8f2lsRmUiIZdACfyL+R1OqA+DS7vxuyeI=,tag:Dy3+kQl+vBY8GLObY/qqDw==,type:bool]
+some_more_data:
+ hello: ENC[AES256_GCM,data:UKybdeY=,iv:SyP3DdAFPOOXZkAkHtKiauH5t0T/lUZbGdo+SI9g80k=,tag:4mgLyrtWWdbNbXolho2v2A==,type:str]
+sops:
+ kms: []
+ gcp_kms: []
+ azure_kv: []
+ lastmodified: '2019-07-17T15:52:25Z'
+ mac: ENC[AES256_GCM,data:CURHSaJhLt4l9yQQqUtkrXZNDCj00SMYM6eal4U/u2XbitH1mR0nsLsRlePo2KPu7NbrJ7P46nqIwuvBbWrF2MGKa3ucTdY1pyJJCWD0+OK1+lV3P8T47/ZxN7r+aCDHVue8StRIcufvtLbtZ/01pDeg3gviSH1JwtP3VaCeihc=,iv:OQ0imfPs9JtAB2Np3V+WXbA+LwhUdQzZaIz6ZwJ3glU=,tag:HAHjEXsaPDvw2zW+d9WFCg==,type:str]
+ pgp:
+ - created_at: '2019-07-17T15:51:36Z'
+ enc: |-
+ -----BEGIN PGP MESSAGE-----
+
+ wYwDEEVDpnzXnMABBAB/NzaqcAN5K1JEC3RTCZcQZ/9GfZ8gnxIeVWArH1S7qN1m
+ 6y+m7/oYM/xEH76abBdE85lLdoFHsuKEzMcfhdYiyjjwy2zJHkzzb3NMwFqgBeeu
+ ok9L3xn4LswDNxRgM+OhQqvkg2+i5QgXUcDNxEBLsNIEhyR1eZnIUafeRX3ht9Lg
+ AeTRLKmYvzSNcsTLFEXGVs2w4bi14KjgzOGiNuCJ4o6QJ9DgUuW8SVR1ytG0Mj+e
+ FoUTmga/cV996OasIPD/iUqOgJCFD+Cj5AtclYK8JbSoPIJYpc2CGAbi6bZ6LOGQ
+ sgA=
+ =O39v
+ -----END PGP MESSAGE-----
+ fp: 1022470DE3F0BC54BC6AB62DE05550BC07FB1A0A
+ unencrypted_suffix: _unencrypted
+ version: 3.3.1
+```
+
+None of the values in our plain text YAML file are visible, they've all been
+encrypted! We can make some further edits to the file by running
+`sops quickstart.yaml`. We don't need to specify our PGP key fingerprint
+again, as the SOPS file format stores this information already.
+
+For more ways to use `sops`, please consult the rest of the documentation.
diff --git a/docs/usage/decrypting_files.md b/docs/usage/decrypting_files.md
new file mode 100644
index 000000000..1c78ceca7
--- /dev/null
+++ b/docs/usage/decrypting_files.md
@@ -0,0 +1,36 @@
+# Decrypting files
+
+Suppose you have an encrypted SOPS file, and would like to decrypt it. As an
+example, let's use the file from [Encrypting files](usage/encrypting_files.md):
+
+```bash
+$ cat my_file.enc
+{
+ "data": "ENC[AES256_GCM,data:2jQNm13QiRfVWf/nEk8=,iv:s7vZVoMFcQ32TvhQixVc6ZxC5EevnTBG3UxlQ8lD1iM=,tag:sa6j6Im4tQDCqt2oHCWXjg==,type:str]",
+ "sops": {
+ "kms": null,
+ "gcp_kms": null,
+ "azure_kv": null,
+ "lastmodified": "2019-07-17T19:12:15Z",
+ "mac": "ENC[AES256_GCM,data:5uvzX7kRrFCL5a58js1ls4ALltUtqqi5ZhoQGMbXDZdTDxYaCLkoFTg4PCOil7133g1uaye6f9AjPgvEUGpPFONWg6g9k6k7fN/AsgSiYSZUHD1yCQZhyiKIVhxrnFV+0v0fH5Zwm7bZAqrUrzaH3YGpo6ces9iBSsHMCEHDGdc=,iv:7LX+irD4XrmuHsCYKJvd4BsP5TMkWeLSc6I+heg+c0s=,tag:33WZIPkU5LOMny0L7cx6fg==,type:str]",
+ "pgp": [
+ {
+ "created_at": "2019-07-17T19:12:15Z",
+ "enc": "-----BEGIN PGP MESSAGE-----\n\nwYwDEEVDpnzXnMABBACsHmqe5BT4S4O684E39czJrmGkRTSMYX9YCnSVNUVMkwNY\n+JL6FmuLC13320weeO3xL9CCDJIKAGixTehi5JDVY1rK9bCuUTQrjN8NMEHPAZn8\nRvB/W0hKkqaOOpAjq2syp2RjTnNOn8cqkP80Jo9w3BXIJJitBJuKC850Vh0FJdLg\nAeTzXWkhERBsxwJ4ADawDWCU4XPi4M7gDOHmiOAa4shf6zjgwOU5PFnDtDG0kLCl\n49NAKBboOSyEx9sFA4on3j7GLXnroOCj5OwgcsBqIjxerkXizChBS1ziKXEME+Gc\neAA=\n=snqD\n-----END PGP MESSAGE-----",
+ "fp": "1022470DE3F0BC54BC6AB62DE05550BC07FB1A0A"
+ }
+ ],
+ "unencrypted_suffix": "_unencrypted",
+ "version": "3.3.1"
+ }
+}
+```
+
+Let's decrypt it:
+
+```bash
+$ sops --decrypt my_file.enc
+hello, world!
+```
+
+As expected, the original file contents are returned and printed to standard output.
diff --git a/docs/usage/editing_files.md b/docs/usage/editing_files.md
new file mode 100644
index 000000000..904f1f0ff
--- /dev/null
+++ b/docs/usage/editing_files.md
@@ -0,0 +1,82 @@
+# Editing files
+
+## Existing files
+
+Suppose you have an encrypted SOPS file, and would like to edit it. As an
+example, let's use the file from [Encrypting files](usage/encrypting_files.md):
+
+```bash
+$ cat my_file.enc
+{
+ "data": "ENC[AES256_GCM,data:2jQNm13QiRfVWf/nEk8=,iv:s7vZVoMFcQ32TvhQixVc6ZxC5EevnTBG3UxlQ8lD1iM=,tag:sa6j6Im4tQDCqt2oHCWXjg==,type:str]",
+ "sops": {
+ "kms": null,
+ "gcp_kms": null,
+ "azure_kv": null,
+ "lastmodified": "2019-07-17T19:12:15Z",
+ "mac": "ENC[AES256_GCM,data:5uvzX7kRrFCL5a58js1ls4ALltUtqqi5ZhoQGMbXDZdTDxYaCLkoFTg4PCOil7133g1uaye6f9AjPgvEUGpPFONWg6g9k6k7fN/AsgSiYSZUHD1yCQZhyiKIVhxrnFV+0v0fH5Zwm7bZAqrUrzaH3YGpo6ces9iBSsHMCEHDGdc=,iv:7LX+irD4XrmuHsCYKJvd4BsP5TMkWeLSc6I+heg+c0s=,tag:33WZIPkU5LOMny0L7cx6fg==,type:str]",
+ "pgp": [
+ {
+ "created_at": "2019-07-17T19:12:15Z",
+ "enc": "-----BEGIN PGP MESSAGE-----\n\nwYwDEEVDpnzXnMABBACsHmqe5BT4S4O684E39czJrmGkRTSMYX9YCnSVNUVMkwNY\n+JL6FmuLC13320weeO3xL9CCDJIKAGixTehi5JDVY1rK9bCuUTQrjN8NMEHPAZn8\nRvB/W0hKkqaOOpAjq2syp2RjTnNOn8cqkP80Jo9w3BXIJJitBJuKC850Vh0FJdLg\nAeTzXWkhERBsxwJ4ADawDWCU4XPi4M7gDOHmiOAa4shf6zjgwOU5PFnDtDG0kLCl\n49NAKBboOSyEx9sFA4on3j7GLXnroOCj5OwgcsBqIjxerkXizChBS1ziKXEME+Gc\neAA=\n=snqD\n-----END PGP MESSAGE-----",
+ "fp": "1022470DE3F0BC54BC6AB62DE05550BC07FB1A0A"
+ }
+ ],
+ "unencrypted_suffix": "_unencrypted",
+ "version": "3.3.1"
+ }
+}
+```
+
+Let's edit it:
+
+```bash
+$ sops my_file.enc
+```
+
+This will open the decrypted, plain-text file in your editor. You can then make
+any changes you desire, save the file, and exit your editor. The encrypted file
+will be updated with the modifications you made.
+
+## New files
+
+`sops` lets you create new encrypted files directly as well. You will be shown
+an example file for whichever storage format you are using. You can edit that
+example file and save, and your changes will be encrypted and persisted in the
+file.
+
+## Advantages over manually decrypting, editing, and then reencrypting a file
+
+Editing files directly through `sops` has a big advantage: the [data
+key](internals/encryption_protocol.md) and other cryptographic values are
+preserved. For formats that have some sort of key-value structure, this allows
+`sops` to leave encrypted values that were not modified completely unchanged,
+which in turn allows users to get an idea of *what* was modified in a file
+by using version control systems and differs, even if they do not have access
+to the plain-text decrypted data at all.
+
+## What editor will `sops` use?
+
+`sops` uses the `EDITOR` environment variable to decide what editor to use. If
+the variable is not set, `sops` will then try a few common editors found on
+most systems.
+
+## GUI Editors (Sublime, Atom, et al.)
+
+Some editors, especially GUI editors, spawn a new process and then immediately
+exit when executed. `sops` relies on your editor exiting to know when you're
+done editing the file. Because those editors exit immediately, `sops` will
+always think you haven't modified the file at all.
+
+To work around this, consult your editor's documentation for an option that
+will make it wait until it is closed for the process to exit. This is sometimes
+offered as a command line flag. In that case, you will need to wrap your editor
+in a script that passes a command line flag, since the `EDITOR` environment
+variable does not accept arguments. For example, for Atom:
+
+```bash
+#!/bin/bash
+atom -w
+```
+
+Make that script executable and then set `EDITOR` to its location.
diff --git a/docs/usage/encrypting_files.md b/docs/usage/encrypting_files.md
new file mode 100644
index 000000000..1e2aa0222
--- /dev/null
+++ b/docs/usage/encrypting_files.md
@@ -0,0 +1,40 @@
+# Encrypting files
+
+Suppose you already have a plain-text, unencrypted file, and would like `sops` to encrypt it:
+
+```bash
+$ cat my_file
+hello, world!
+```
+
+You can do so as follows:
+
+```bash
+$ sops --encrypt my_file
+{
+ "data": "ENC[AES256_GCM,data:45IFIHXi0pogtNwIE90=,iv:Lu7aGNAHCvwi3VMyJewjhj+pxYCi05gdTpYC1DKFmg8=,tag:YlRb8za8o1lJ4XiTj/KxfA==,type:str]",
+ "sops": {
+ "kms": null,
+ "gcp_kms": null,
+ "azure_kv": null,
+ "lastmodified": "2019-07-17T18:59:59Z",
+ "mac": "ENC[AES256_GCM,data:bYHCF4z/wxIwUBDEEvyCwqUu2v+LWxRikYnI9fC2OVnwcIDadH/xhK1zIrRxq0HugeQYSar5GsCjgy4jhiaxfG1RlQZnkL2Iz/wT+ZdxwY4yeLJ+4/tRwjxCqhrmq2uTihskP7RFVLp6TqM9r/JAyCzqDHxScPmAMVydDTieYaU=,iv:jD4yvBNS075aCbv+OvRdFXjOD13etsux01XL2d5F2cw=,tag:vxm/paFnCtEmIgqkv4h+OQ==,type:str]",
+ "pgp": [
+ {
+ "created_at": "2019-07-17T18:59:58Z",
+ "enc": "-----BEGIN PGP MESSAGE-----\n\nwYwDEEVDpnzXnMABBAClqG2V54awfbG/6CuIlnawf5FnFizG4lCV9iXHHeth/r1W\n+1ejBKY9EcrnW/o59adGFmknDsIDAmJaQE3V9fruOdtMixr9MjkNqUfT90c/mCZ9\nV+yA4UfDoZuNzRk3Bkb/7PuT02X9eASdn4V3ShbGmbdMk37NQPel9QXcuAVlqtLg\nAeRzhNVGICGVGpLuzCnvP4DN4XZR4IfghuEe2eD14lmfIRLg7+VDb4IMf81bpomg\ndqXmTpbTsV/5gQxjdijsvh5QRDO2duDe5LTwyRWkZgxtkMee0XZKCVLi5gmRNeFO\n8gA=\n=Udaa\n-----END PGP MESSAGE-----",
+ "fp": "1022470DE3F0BC54BC6AB62DE05550BC07FB1A0A"
+ }
+ ],
+ "unencrypted_suffix": "_unencrypted",
+ "version": "3.3.1"
+ }
+}
+```
+
+!> You need at least one [master key](encryption_providers/README.md) available
+to encrypt a file.
+
+The encrypted file is written to standard output. If you want to save it
+permanentely, you can either use your shell to redirect the output to a file,
+or you can operate on the file [in-place](usage/operate_in_place.md).
diff --git a/docs/usage/git_differ.md b/docs/usage/git_differ.md
new file mode 100644
index 000000000..d941e8324
--- /dev/null
+++ b/docs/usage/git_differ.md
@@ -0,0 +1,24 @@
+# `sops` as a git differ
+
+You most likely want to store your encrypted files in a version control
+repository. `sops` can be used with git to decrypt files when showing diffs
+between versions. This is very handy for reviewing changes or visualizing
+history.
+
+To configure sops to decrypt files during diff, create a `.gitattributes` file
+at the root of your repository that contains a filter and a command:
+
+```
+*.yaml diff=sopsdiffer
+```
+
+Here we only care about YAML files. ``sopsdiffer`` is an arbitrary name that we
+then map to a `sops` command in the git configuration file of the repository.
+
+```bash
+$ git config diff.sopsdiffer.textconv "sops -d"
+```
+
+With this in place, calls to ``git diff`` will decrypt both previous and
+current versions of the target file prior to displaying the diff. And it even
+works with git client interfaces, because they call git diff under the hood!
diff --git a/docs/usage/key_groups.md b/docs/usage/key_groups.md
new file mode 100644
index 000000000..292a340fc
--- /dev/null
+++ b/docs/usage/key_groups.md
@@ -0,0 +1,81 @@
+# Key groups
+
+By default, `sops` encrypts its [data key](internals/encryption_protocol.md)
+with each of the [master keys](encryption_providers/README.md), such that if
+any of the master keys is available, the file can be decrypted. However, it is
+sometimes desirable to require access to multiple master keys in order to
+decrypt files. This can be achieved with key groups.
+
+When using key groups in sops, the data key is split into fragments such that
+master keys from multiple groups are required to decrypt a file. `sops` uses
+[Shamir's Secret Sharing](TODO) to split the data key such that each key group
+has a fragment, each key in the key group can decrypt that fragment, and a
+configurable number of fragments (threshold) are needed to decrypt and piece
+together the complete data key. When decrypting a file using multiple key
+groups, `sops` goes through the key groups in order, and for each group, tries
+to recover its corresponding fragment of the data key using a master key from
+that group. Once the fragment is recovered, `sops` moves on to the next group,
+until enough fragments have been recovered to obtain the complete data key.
+
+By default, the threshold is set to the number of key groups. For example, if
+you have three key groups configured in your SOPS file and you don't override
+the default threshold, then one master key from each of the three groups will
+be required to decrypt the file.
+
+## The `sops groups` subcommand
+
+Management of key groups is performed through the `sops groups` subcommand.
+
+### Adding a key group to a file
+
+You can add groups to a file through the `sops groups add` command. For example, to add a new key group to an existing file with 3 PGP keys and 3 AWS KMS keys, one could do as follows:
+
+```bash
+$ sops groups add --file my_file.enc --pgp fingerprint1 --pgp fingerprint2 --pgp fingerprint3 --kms arn1 --kms arn2 --kms arn3
+```
+
+### Deleting key groups from a file
+
+Similarly, key groups can be deleted from encrypted files by their index with
+the `sops groups delete` command. For example, to delete the first key group
+(group number 0, as groups are zero-indexed) in a file:
+
+```bash
+$ sops groups delete --file my_file.enc 0
+```
+
+?> Currently, you can see the order of the key groups in a file by inspecting
+the encrypted file directly without using `sops` (i.e., with `cat`, `less` or
+your favorite editor)
+
+## `.sops.yaml`
+
+The [`.sops.yaml` configuration file](sops_yaml_config_file.md) also contains options related to
+key groups, and as such it can be used as an alternative to the `sops groups`
+subcommand.
+
+When creating a new file using the rules on `.sops.yaml`, the Shamir threshold
+can also be specified through the `--shamir-secret-sharing-threshold` flag.
+
+## The `sops updatekeys` subcommand
+
+In some cases, it might be more convenient to use rules like those in
+`.sops.yaml` to manage key groups. However, these only apply to new files. The
+`sops updatekeys` subcommand updates the key groups in existing files based on
+the matching rules in the `.sops.yaml` configuration file. Essentially, this
+updates the key groups in the file such that they end up as if the file was
+newly created.
+
+```bash
+$ sops updatekeys example.yaml
+2019/07/18 16:03:43 Syncing keys for file example.yaml
+The following changes will be made to the file's groups:
+Group 1
+ 1022470DE3F0BC54BC6AB62DE05550BC07FB1A0A
+--- 85D77543B3D624B63CEA9E6DBC17301B491B3F21
+Is this okay? (y/n):y
+2019/07/18 16:03:53 File example.yaml synced with new keys
+```
+
+This can be more convenient than the `sops groups` subcommand when, for
+example, we want to delete a single key from a key group.
diff --git a/docs/usage/key_rotation.md b/docs/usage/key_rotation.md
new file mode 100644
index 000000000..362fc6046
--- /dev/null
+++ b/docs/usage/key_rotation.md
@@ -0,0 +1,11 @@
+# Key rotation
+
+It is considered group practice to rotate cryptographic keys every once in a
+while. `sops` supports rotation of its data key:
+
+```bash
+$ sops --rotate my_file.enc
+```
+
+!> Rotating the data key requires encryption access to all master keys used in
+a file
diff --git a/docs/usage/publishing_files.md b/docs/usage/publishing_files.md
new file mode 100644
index 000000000..394043c74
--- /dev/null
+++ b/docs/usage/publishing_files.md
@@ -0,0 +1,45 @@
+# Publishing files
+
+The `sops publish` command publishes a file to a pre-configured destination.
+These destinations typically feed into production systems that consume the
+secrets.
+
+Destination configuration resides in the [`.sops.yaml` configuration
+file](sops_yaml_config_file.md).
+
+## Publication targets
+
+A variety of publication targets are supported. We make a distinction between
+publication targets that manage at-rest encryption themselves and those that do
+not.
+
+// TODO this is confusing
+// For instance, why is Vault secure enough to store plain text secrets, but S3 isn't?
+// After all, S3 encrypts at rest as well, and also has access controls around it.
+// I think this might have been designed with the needs of Mozilla in mind.
+
+When the target does not manage encryption itself, SOPS will still be
+responsible for keeping the file encrypted. As such, when publishing to these
+targets, SOPS offers the option to reencrypt the files with a new set of keys.
+Typically, you'd reencrypt the file with keys that only production systems have
+access to. Recreation rules are supported in the [`.sops.yaml` configuration
+file](sops_yaml_config_file.md).
+
+For targets that manage encryption themselves, SOPS stores the plain-text,
+unencrypted data on the target, and the target is responsible for ensuring the
+data is stored securely, encrypted at rest and with appropriate access
+controls.
+
+### AWS S3
+
+SOPS can publish files to S3 buckets.
+
+?> S3 does *not* manage encryption itself
+
+### Google Cloud Storage
+
+SOPS can publish files to Google Cloud Storage buckets.
+
+?> Google Cloud Storage does *not* manage encryption itself
+
+### Hashicorp Vault