diff --git a/_docs-sources/products.md b/_docs-sources/products.md
index 3ee109fa60..f6a8a9e0d2 100644
--- a/_docs-sources/products.md
+++ b/_docs-sources/products.md
@@ -16,27 +16,21 @@ import CenterLayout from "/src/components/CenterLayout"
-Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Purus gravida quis blandit turpis cursus.
+A collection of reusable code that enables you to deploy and manage infrastructure quickly and reliably.
-Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Purus gravida quis blandit turpis cursus.
+An end-to-end tech stack built using best practices on top of our Infrastructure as Code Library, deployed into your AWS accounts.
-Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Purus gravida quis blandit turpis cursus.
+A framework for running secure deployments for infrastructure code and application code.
-Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Purus gravida quis blandit turpis cursus.
-
-
-Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Purus gravida quis blandit turpis cursus.
+Gain access to all resources included in your Gruntwork subscription.
diff --git a/_docs-sources/refarch/access/how-to-auth-CLI/index.md b/_docs-sources/refarch/access/how-to-auth-CLI/index.md
new file mode 100644
index 0000000000..a9d878bed1
--- /dev/null
+++ b/_docs-sources/refarch/access/how-to-auth-CLI/index.md
@@ -0,0 +1,55 @@
+# Authenticate via the AWS command line interface (CLI)
+
+CLI access requires [AWS access keys](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html). We recommend using [aws-vault](https://github.com/99designs/aws-vault) for managing all aspects related to CLI authentication. To use `aws-vault` you will need to generate AWS Access Keys for your IAM user in the security account.
+
+:::tip
+
+`aws-vault` is not the only method which can be used to authenticate on the CLI. Please refer to [A Comprehensive Guide to Authenticating to AWS on the Command Line](https://blog.gruntwork.io/a-comprehensive-guide-to-authenticating-to-aws-on-the-command-line-63656a686799) for several other options.
+
+:::
+
+:::info
+
+MFA is required for the Reference Architecture, including on the CLI. See [configuring your IAM user](/refarch/access/setup-auth/#configure-your-iam-user) for instructions on setting up an MFA token.
+
+:::
+
+## Access resources in the security account
+
+To authenticate to the security account, you only need your AWS access keys and an MFA token. See [the guide](https://github.com/99designs/aws-vault#quick-start) on adding credentials to `aws-vault`.
+
+You should be able to run the following command using AWS CLI
+
+```bash
+aws-vault exec -- aws sts get-caller-identity
+```
+
+and expect to get an output with your user's IAM role:
+
+```json
+{
+ "UserId": "AIDAXXXXXXXXXXXX”,
+ "Account": “",
+ "Arn": "arn:aws:iam:::user/"
+}
+```
+
+## Accessing all other accounts
+
+To authenticate to all other accounts (e.g., dev, stage, prod), you will need the ARN of an IAM Role in that account to assume. To configure accessing accounts using assumed roles with `aws-vault` refer to [these instructions](https://github.com/99designs/aws-vault#roles-and-mfa).
+
+Given the following command (where `YOUR_ACCOUNT_PROFILE_NAME` will be any account other than your security account)
+
+```bash
+aws-vault exec -- aws sts get-caller-identity
+```
+
+you should expect to see the following output:
+
+```json
+{
+ "UserId": "AIDAXXXXXXXXXXXX",
+ "Account": "",
+ "Arn": "arn:aws:sts:::assumed-role//11111111111111111111"
+}
+```
diff --git a/_docs-sources/refarch/access/how-to-auth-aws-web-console/index.md b/_docs-sources/refarch/access/how-to-auth-aws-web-console/index.md
new file mode 100644
index 0000000000..77e6ec3b24
--- /dev/null
+++ b/_docs-sources/refarch/access/how-to-auth-aws-web-console/index.md
@@ -0,0 +1,26 @@
+# Authenticating to the AWS web console
+
+## Authenticate to the AWS Web Console in the security account
+
+To authenticate to the security account, you will need:
+
+1. IAM User Credentials. See [setting up initial access](/refarch/access/setup-auth/) for how to create IAM users.
+1. An MFA Token. See [Configuring your IAM user](/refarch/access/setup-auth/#configure-your-iam-user).
+1. The login URL. This should be of the format `https://.signin.aws.amazon.com/console`.
+
+## Authenticate to the AWS Web Console in all other accounts
+
+To authenticate to any other account (e.g., dev, stage, prod), you need to:
+
+1. Authenticate to the security account. All IAM users are defined in this account, you must always authenticate to it first.
+1. [Assume an IAM Role in the other AWS account](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-console.html). To access other accounts, you switch to an IAM Role defined in that account.
+
+:::note
+Note that to be able to access an IAM Role in some account, your IAM User must be in an IAM Group that has permissions to assume that IAM Role.
+:::
+
+See the `cross-account-iam-roles` module for the [default set of IAM Roles](https://github.com/gruntwork-io/terraform-aws-security/blob/main/modules/cross-account-iam-roles/README.md#iam-roles-intended-for-human-users) that exist in each account. For example, to assume the allow-read-only-access-from-other-accounts IAM Role in the prod account, you must be in the \_account.prod-read-only IAM Group. See [Configure other IAM Users](/refarch/access/setup-auth/#configure-other-iam-users) for how you add users to IAM Groups.
+
+:::note
+Not all of the default roles referenced in the `cross-account-iam-roles` module are deployed in each account.
+:::
diff --git a/_docs-sources/refarch/access/how-to-auth-aws/index.md b/_docs-sources/refarch/access/how-to-auth-aws/index.md
deleted file mode 100644
index 38ff25b2d5..0000000000
--- a/_docs-sources/refarch/access/how-to-auth-aws/index.md
+++ /dev/null
@@ -1,47 +0,0 @@
-# Command Line (CLI) Authentication
-
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
-
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
-
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
-
-## Accessing resources
-
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
-
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
-
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
-
-## Using aws-vault with the Reference Architecture
-
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
-
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
-
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
-
-# AWS Web Console Authentication
-
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
-
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
-
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
-
-## Security account difference
-
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
-
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
-
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
-
-## How the IAM roles work
-
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
-
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
-
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
diff --git a/_docs-sources/refarch/access/how-to-auth-ec2/index.md b/_docs-sources/refarch/access/how-to-auth-ec2/index.md
index 7dde22a1c8..8f61b2ce0d 100644
--- a/_docs-sources/refarch/access/how-to-auth-ec2/index.md
+++ b/_docs-sources/refarch/access/how-to-auth-ec2/index.md
@@ -1,9 +1,63 @@
-# SSH to an EC2 Instance
+# SSH to EC2 Instances
+You can SSH to any of your EC2 Instances in the Reference Architecture in two different ways:
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
+1. `ssh-grunt` (Recommended)
+1. EC2 Key Pairs (For emergency / backup use only)
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
+## `ssh-grunt` (Recommended)
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
+[`ssh-grunt`](../../../reference/modules/terraform-aws-security/ssh-grunt/) is a tool developed by Gruntwork that automatically syncs user accounts from AWS IAM to your servers to allow individual developers to SSH onto EC2 instances using their own username and SSH keys.
+In this section, you will learn how to SSH to an EC2 instance in your Reference Architecture using `ssh-grunt`. Every EC2 instance has `ssh-grunt` installed by default.
+
+### Add users to SSH IAM Groups
+
+When running `ssh-grunt`, each EC2 instance specifies from which IAM Groups it will allow SSH access, and SSH access with sudo permissions. By default, these IAM Group names are `ssh-grunt-users` and `ssh-grunt-sudo-users`, respectively. To be able to SSH to an EC2 instance, your IAM User must be added to one of these IAM Groups (see Configure other IAM Users for instructions).
+
+### Upload your public SSH key
+
+1. Authenticate to the AWS Web Console in the security account.
+1. Go to your IAM User profile page, select the "Security credentials" tab, and click "Upload SSH public key".
+1. Upload your public SSH key (e.g. `~/.ssh/id_rsa.pub`). Do NOT upload your private key.
+
+### Determine your SSH username
+
+Your username for SSH is typically the same as your IAM User name. However, if your IAM User name has special characters that are not allowed by operating systems (e.g., most punctuation is not allowed), your SSH username may be a bit different, as specified in the `ssh-grunt` [documentation](../../../reference/modules/terraform-aws-security/ssh-grunt/). For example:
+
+1. If your IAM User name is `jane`, your SSH username will also be `jane`.
+1. If your IAM User name is `jane@example.com`, your SSH username will be `jane`.
+1. If your IAM User name is `_example.jane.doe`, your SSH username will be `example_jane_doe`.
+
+
+### SSH to an EC2 instance
+
+Since most EC2 instances in the Reference Architecture are deployed into private subnets, you won't be able to access them over the public Internet. Therefore, you must first connect to the VPN server. See [VPN Authentication](../how-to-auth-vpn/index.md) for more details.
+
+Given that:
+
+1. Your IAM User name is jane.
+1. You've uploaded your public SSH key to your IAM User profile.
+1. Your private key is located at `/Users/jane/.ssh/id_rsa` on your local machine.
+1. Your EC2 Instance's IP address is 1.2.3.4.
+
+
+First, add your SSH Key into the SSH Agent using the following command:
+
+```bash
+ssh-add /Users/jane/.ssh/id_rsa
+```
+
+Then, use this command to SSH to the EC2 Instance:
+
+```bash
+ssh jane@1.2.3.4
+```
+
+You should now be able to execute commands on the instance.
+
+## EC2 Key Pairs (For emergency / backup use only)
+
+When you launch an EC2 Instance in AWS, you can specify an EC2 Key Pair that can be used to SSH into the EC2 Instance. This suffers from an important problem: usually more than one person needs access to the EC2 Instance, which means you have to share this key with others. Sharing secrets of this sort is a security risk. Moreover, if someone leaves the company, to ensure they no longer have access, you'd have to change the Key Pair, which requires redeploying all of your servers.
+
+As part of the Reference Architecture deployment, Gruntwork will create EC2 Key Pairs and put the private keys into AWS Secrets Manager. These keys are there only for emergency / backup use: e.g., if there's a bug in `ssh-grunt` that prevents you from accessing your EC2 instances. We recommend only giving a handful of trusted admins access to these Key Pairs.
diff --git a/_docs-sources/refarch/access/how-to-auth-vpn/index.md b/_docs-sources/refarch/access/how-to-auth-vpn/index.md
index 615cefaaa7..06fe05b672 100644
--- a/_docs-sources/refarch/access/how-to-auth-vpn/index.md
+++ b/_docs-sources/refarch/access/how-to-auth-vpn/index.md
@@ -1,9 +1,43 @@
-# VPN Authentcation
+# VPN Authentication
+Most of the AWS resources that comprise the Reference Architecture run in private subnets, which means they do not have a public IP address, and cannot be reached directly from the public Internet. This reduces the "surface area" that attackers can reach. Of course, you still need access into the VPCs so we exposed a single entrypoint into the network: an [OpenVPN server](https://openvpn.net/).
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
+## Install an OpenVPN client
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
+There are free and paid OpenVPN clients available for most major operating systems. Popular options include:
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
+1. OS X: [Viscosity](https://www.sparklabs.com/viscosity/) or [Tunnelblick](https://tunnelblick.net/).
+1. Windows: [official client](https://openvpn.net/index.php/open-source/downloads.html).
+1. Linux:
+ ```bash title="Debian"
+ apt-get install openvpn
+ ```
+
+ ```bash title="Redhat"
+ yum install openvpn
+ ```
+
+## Join the OpenVPN IAM Group
+
+Your IAM User needs access to SQS queues used by the OpenVPN server. Since IAM users are defined only in the security account, and the OpenVPN servers are defined in separate AWS accounts (stage, prod, etc), that means you need to authenticate to the accounts with the OpenVPN servers by assuming an IAM Role that has access to the SQS queues in those accounts.
+
+To be able to assume an IAM Role, your IAM user needs to be part of an IAM Group with the proper permissions, such as `_account.xxx-full-access` or `_account.xxx-openvpn-users`, where `xxx` is the name of the account you want to access (stage, prod, etc). See [Configure other IAM users](/refarch/access/setup-auth/#configure-other-iam-users) for instructions on adding users to IAM Groups.
+
+## Use openvpn-admin to generate a configuration file
+
+To connect to an OpenVPN server, you need an OpenVPN configuration file, which includes a certificate that you can use to authenticate. To generate this configuration file, do the following:
+
+1. Install the latest [`openvpn-admin binary`](https://github.com/gruntwork-io/terraform-aws-openvpn/releases) for your OS.
+
+1. Authenticate to AWS via the CLI. You will need to assume an IAM Role in the AWS account with the OpenVPN server you're trying to connect to. This IAM Role must have access to the SQS queues used by OpenVPN server. Typically, the `allow-full-access-from-other-accounts` or `openvpn-server-allow-certificate-requests-for-external-accounts` IAM Role is what you want.
+
+1. Run `openvpn-admin request --aws-region --username `.
+
+1. This will create your OpenVPN configuration file in your current directory.
+
+1. Load this configuration file into your OpenVPN client.
+
+## Connect to one of your OpenVPN servers
+
+To connect to an OpenVPN server in one of your app accounts (Dev, Stage, Prod), click the "Connect" button next to your configuration file in the OpenVPN client. After a few seconds, you should be connected. You will now be able to access all the resources within the AWS network (e.g., SSH to EC2 instances in private subnets) as if you were "in" the VPC itself.
diff --git a/_docs-sources/refarch/access/setup-auth/index.md b/_docs-sources/refarch/access/setup-auth/index.md
index 2d8bdd9929..44db323f16 100644
--- a/_docs-sources/refarch/access/setup-auth/index.md
+++ b/_docs-sources/refarch/access/setup-auth/index.md
@@ -1,27 +1,123 @@
# Set up AWS Auth
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
+## Configure root users
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
+Each of your AWS accounts has a root user that you need to configure. When you created the child AWS accounts (dev, stage, prod, etc), you provided the root user's email address for each account; if you don't know what those email addresses were, you can log in to the root account (the parent of the AWS Organization) and go to the AWS Organizations Console to find them.
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
+Once you have the email addresses, you'll need the passwords. When you create child accounts in an AWS organization, AWS will not allow you to set the root password. In order to generate the root password:
-## 1. Configure root user
+1. Go to the AWS Console.
+1. If you had previously signed into some other AWS account as an IAM User, rather than a root user, click "Sign-in using root account credentials."
+1. Enter the email address of the root user.
+1. Click "Forgot your password" to reset the password.
+1. Check the email address associated with the root user account for a link you can use to create a new password.
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
+:::danger
+Please note that the root user account can do anything in your AWS account, bypassing the security restrictions you put in place, so you need to take extra care with protecting this account.
+:::
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
+We strongly recommend that when you reset the password for each account, you also:
-## 2. Configure your IAM users
+1. Use a strong password: preferably 30+ characters, randomly generated, and stored in a secrets manager.
+1. Enable Multi-Factor Auth (MFA): Follow [these instructions](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html#enable-virt-mfa-for-root) to enable MFA for the root user.
+ After this initial set up, you should _not_ use the root user account afterward except in very rare circumstances. (e.g., if you get locked out of your IAM User account and no one has permissions to reset your password). For day-to-day tasks, you should use an IAM User instead, as described in the next section.
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
+Please note that you'll have to repeat the process above of resetting the password and enabling MFA for every account in your organization: dev, stage, prod, shared, security, logs, and the root account.
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
+## Configure your IAM user
-## 3. Configure other IAM users
+The security account defines and manages all IAM Users. When deploying your Reference Architecture, Gruntwork creates an IAM User with admin permissions in the security account. The password for the IAM User is encrypted via PGP using [Keybase](https://keybase.io) (you'll need a free account) and is Base64-encoded.
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
+To access the Terraform state containing the password, you need to already be authenticated to the account. Thus to get access to the initial admin IAM User, we will use the root user credentials. To do this, you can either:
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
+- Log in to the AWS Web Console using the root user credentials for the security account and set up the password and AWS Access Keys for the IAM User.
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
+- Use the [Gruntwork CLI](https://github.com/gruntwork-io/gruntwork/) to rotate the password using the command:
+
+ ```bash
+ gruntwork aws reset-password --iam-user-name
+ ```
+
+Once you have access via your IAM user, finish hardening your security posture:
+
+1. Enable MFA for your IAM User by following [these instructions](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable.html). MFA is required by the Reference Architecture, and you won't be able to access any other accounts without it.
+
+ :::note
+ Note that the name of the MFA must be exactly the same as the AWS IAM Username
+ :::
+
+1. Log out and log back in — After enabling MFA, you need to log out and then log back in. This forces AWS to prompt you for your MFA token.
+
+ :::caution
+ Until you enable MFA, you will not be able to access anything else in the web console.
+ :::
+
+1. Create access keys for yourself by following [these instructions](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html). Store the access keys in a secrets manager. You will need these to authenticate to AWS from the command-line.
+
+## Configure other IAM users
+
+Now that your IAM user is all set up, you can configure IAM users for the rest of your team.
+
+:::note
+Each of your users will need a free [Keybase](https://keybase.io/) account so that their credentials can be encrypted just for their access.
+:::
+
+All of the IAM users are managed as code in the security account in the `account-baseline-app` module. If you open the `terragrunt.hcl` file in that repo, you should see the list of users, which will look something like:
+
+```yaml
+jane@acme.com:
+ create_access_keys: false
+ create_login_profile: true
+ groups:
+ - full-access
+ pgp_key: keybase:jane_on_keybase
+```
+
+Here's how you would add two more users, Alice and Bob, to your security account:
+
+```yaml
+jane@acme.com:
+ create_login_profile: true
+ groups:
+ - full-access
+ pgp_key: keybase:jane_on_keybase
+alice@acme.com:
+ create_login_profile: true
+ groups:
+ - _account.dev-full-access
+ - _account.stage-full-access
+ - _account.prod-full-access
+ - iam-user-self-mgmt
+ pgp_key: keybase:alice_on_keybase
+bob@acme.com:
+ create_login_profile: true
+ groups:
+ - _account.prod-read-only
+ - ssh-grunt-sudo-users
+ - iam-user-self-mgmt
+ pgp_key: keybase:bob_on_keybase
+```
+
+A few notes about the code above:
+
+1. **Groups**. We add each user to a set of IAM Groups: for example, we add Alice to IAM Groups that give her admin access in the dev, stage, and prod accounts, whereas Bob gets read-only access to prod, plus SSH access (with `sudo` permissions) to EC2 instances. For the full list of IAM Groups available, see the [IAM Groups module](https://github.com/gruntwork-io/terraform-aws-security/tree/main/modules/iam-groups#iam-groups).
+
+1. **PGP Keys**. We specify a PGP Key to use to encrypt any secrets for that user. Keys of the form `keybase:` are automatically fetched for user `` on [Keybase](https://keybase.io/).
+
+1. **Credentials**. For each user whose `create_login_profile` field is set to `true`, a password will be automatically generated. This password can be used to log in to the web console. This password will be encrypted with the user's PGP key and visible as a Terraform output. After you run `terragrunt apply`, you can copy/paste these encrypted credentials and send them to the user.
+
+To deploy this new code and create the new IAM Users, you will need to:
+
+1. Authenticate to AWS via the CLI.
+
+1. Apply your changes by running `terragrunt apply`.
+
+1. Share the login URL, usernames, and (encrypted) password with your team members.
+
+ :::note
+ Make sure to tell each team member to follow the [Configure your IAM User instructions](#configure-your-iam-user) to log in, reset their password, and enable MFA.
+ :::
+
+ :::caution
+ Enabling MFA is required to access the Reference Architecture
+ :::
diff --git a/docs/products.md b/docs/products.md
index 9165810999..1fe554c8bf 100644
--- a/docs/products.md
+++ b/docs/products.md
@@ -16,27 +16,21 @@ import CenterLayout from "/src/components/CenterLayout"
-Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Purus gravida quis blandit turpis cursus.
+A collection of reusable code that enables you to deploy and manage infrastructure quickly and reliably.
-Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Purus gravida quis blandit turpis cursus.
+An end-to-end tech stack built using best practices on top of our Infrastructure as Code Library, deployed into your AWS accounts.
-Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Purus gravida quis blandit turpis cursus.
+A framework for running secure deployments for infrastructure code and application code.
-Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Purus gravida quis blandit turpis cursus.
-
-
-Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Purus gravida quis blandit turpis cursus.
+Gain access to all resources included in your Gruntwork subscription.
@@ -47,6 +41,6 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
diff --git a/docs/refarch/access/how-to-auth-CLI/index.md b/docs/refarch/access/how-to-auth-CLI/index.md
new file mode 100644
index 0000000000..74dd7ad5da
--- /dev/null
+++ b/docs/refarch/access/how-to-auth-CLI/index.md
@@ -0,0 +1,63 @@
+# Authenticate via the AWS command line interface (CLI)
+
+CLI access requires [AWS access keys](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html). We recommend using [aws-vault](https://github.com/99designs/aws-vault) for managing all aspects related to CLI authentication. To use `aws-vault` you will need to generate AWS Access Keys for your IAM user in the security account.
+
+:::tip
+
+`aws-vault` is not the only method which can be used to authenticate on the CLI. Please refer to [A Comprehensive Guide to Authenticating to AWS on the Command Line](https://blog.gruntwork.io/a-comprehensive-guide-to-authenticating-to-aws-on-the-command-line-63656a686799) for several other options.
+
+:::
+
+:::info
+
+MFA is required for the Reference Architecture, including on the CLI. See [configuring your IAM user](/refarch/access/setup-auth/#configure-your-iam-user) for instructions on setting up an MFA token.
+
+:::
+
+## Access resources in the security account
+
+To authenticate to the security account, you only need your AWS access keys and an MFA token. See [the guide](https://github.com/99designs/aws-vault#quick-start) on adding credentials to `aws-vault`.
+
+You should be able to run the following command using AWS CLI
+
+```bash
+aws-vault exec -- aws sts get-caller-identity
+```
+
+and expect to get an output with your user's IAM role:
+
+```json
+{
+ "UserId": "AIDAXXXXXXXXXXXX”,
+ "Account": “",
+ "Arn": "arn:aws:iam:::user/"
+}
+```
+
+## Accessing all other accounts
+
+To authenticate to all other accounts (e.g., dev, stage, prod), you will need the ARN of an IAM Role in that account to assume. To configure accessing accounts using assumed roles with `aws-vault` refer to [these instructions](https://github.com/99designs/aws-vault#roles-and-mfa).
+
+Given the following command (where `YOUR_ACCOUNT_PROFILE_NAME` will be any account other than your security account)
+
+```bash
+aws-vault exec -- aws sts get-caller-identity
+```
+
+you should expect to see the following output:
+
+```json
+{
+ "UserId": "AIDAXXXXXXXXXXXX",
+ "Account": "",
+ "Arn": "arn:aws:sts:::assumed-role//11111111111111111111"
+}
+```
+
+
+
diff --git a/docs/refarch/access/how-to-auth-aws-web-console/index.md b/docs/refarch/access/how-to-auth-aws-web-console/index.md
new file mode 100644
index 0000000000..e8cb5522e5
--- /dev/null
+++ b/docs/refarch/access/how-to-auth-aws-web-console/index.md
@@ -0,0 +1,34 @@
+# Authenticating to the AWS web console
+
+## Authenticate to the AWS Web Console in the security account
+
+To authenticate to the security account, you will need:
+
+1. IAM User Credentials. See [setting up initial access](/refarch/access/setup-auth/) for how to create IAM users.
+1. An MFA Token. See [Configuring your IAM user](/refarch/access/setup-auth/#configure-your-iam-user).
+1. The login URL. This should be of the format `https://.signin.aws.amazon.com/console`.
+
+## Authenticate to the AWS Web Console in all other accounts
+
+To authenticate to any other account (e.g., dev, stage, prod), you need to:
+
+1. Authenticate to the security account. All IAM users are defined in this account, you must always authenticate to it first.
+1. [Assume an IAM Role in the other AWS account](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-console.html). To access other accounts, you switch to an IAM Role defined in that account.
+
+:::note
+Note that to be able to access an IAM Role in some account, your IAM User must be in an IAM Group that has permissions to assume that IAM Role.
+:::
+
+See the `cross-account-iam-roles` module for the [default set of IAM Roles](https://github.com/gruntwork-io/terraform-aws-security/blob/main/modules/cross-account-iam-roles/README.md#iam-roles-intended-for-human-users) that exist in each account. For example, to assume the allow-read-only-access-from-other-accounts IAM Role in the prod account, you must be in the \_account.prod-read-only IAM Group. See [Configure other IAM Users](/refarch/access/setup-auth/#configure-other-iam-users) for how you add users to IAM Groups.
+
+:::note
+Not all of the default roles referenced in the `cross-account-iam-roles` module are deployed in each account.
+:::
+
+
+
diff --git a/docs/refarch/access/how-to-auth-aws/index.md b/docs/refarch/access/how-to-auth-aws/index.md
deleted file mode 100644
index e20b88b93c..0000000000
--- a/docs/refarch/access/how-to-auth-aws/index.md
+++ /dev/null
@@ -1,55 +0,0 @@
-# Command Line (CLI) Authentication
-
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
-
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
-
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
-
-## Accessing resources
-
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
-
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
-
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
-
-## Using aws-vault with the Reference Architecture
-
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
-
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
-
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
-
-# AWS Web Console Authentication
-
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
-
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
-
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
-
-## Security account difference
-
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
-
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
-
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
-
-## How the IAM roles work
-
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
-
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
-
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
-
-
-
diff --git a/docs/refarch/access/how-to-auth-ec2/index.md b/docs/refarch/access/how-to-auth-ec2/index.md
index db64d7f05e..6decb2f4aa 100644
--- a/docs/refarch/access/how-to-auth-ec2/index.md
+++ b/docs/refarch/access/how-to-auth-ec2/index.md
@@ -1,17 +1,71 @@
-# SSH to an EC2 Instance
+# SSH to EC2 Instances
+You can SSH to any of your EC2 Instances in the Reference Architecture in two different ways:
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
+1. `ssh-grunt` (Recommended)
+1. EC2 Key Pairs (For emergency / backup use only)
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
+## `ssh-grunt` (Recommended)
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
+[`ssh-grunt`](../../../reference/modules/terraform-aws-security/ssh-grunt/) is a tool developed by Gruntwork that automatically syncs user accounts from AWS IAM to your servers to allow individual developers to SSH onto EC2 instances using their own username and SSH keys.
+In this section, you will learn how to SSH to an EC2 instance in your Reference Architecture using `ssh-grunt`. Every EC2 instance has `ssh-grunt` installed by default.
+
+### Add users to SSH IAM Groups
+
+When running `ssh-grunt`, each EC2 instance specifies from which IAM Groups it will allow SSH access, and SSH access with sudo permissions. By default, these IAM Group names are `ssh-grunt-users` and `ssh-grunt-sudo-users`, respectively. To be able to SSH to an EC2 instance, your IAM User must be added to one of these IAM Groups (see Configure other IAM Users for instructions).
+
+### Upload your public SSH key
+
+1. Authenticate to the AWS Web Console in the security account.
+1. Go to your IAM User profile page, select the "Security credentials" tab, and click "Upload SSH public key".
+1. Upload your public SSH key (e.g. `~/.ssh/id_rsa.pub`). Do NOT upload your private key.
+
+### Determine your SSH username
+
+Your username for SSH is typically the same as your IAM User name. However, if your IAM User name has special characters that are not allowed by operating systems (e.g., most punctuation is not allowed), your SSH username may be a bit different, as specified in the `ssh-grunt` [documentation](../../../reference/modules/terraform-aws-security/ssh-grunt/). For example:
+
+1. If your IAM User name is `jane`, your SSH username will also be `jane`.
+1. If your IAM User name is `jane@example.com`, your SSH username will be `jane`.
+1. If your IAM User name is `_example.jane.doe`, your SSH username will be `example_jane_doe`.
+
+
+### SSH to an EC2 instance
+
+Since most EC2 instances in the Reference Architecture are deployed into private subnets, you won't be able to access them over the public Internet. Therefore, you must first connect to the VPN server. See [VPN Authentication](../how-to-auth-vpn/index.md) for more details.
+
+Given that:
+
+1. Your IAM User name is jane.
+1. You've uploaded your public SSH key to your IAM User profile.
+1. Your private key is located at `/Users/jane/.ssh/id_rsa` on your local machine.
+1. Your EC2 Instance's IP address is 1.2.3.4.
+
+
+First, add your SSH Key into the SSH Agent using the following command:
+
+```bash
+ssh-add /Users/jane/.ssh/id_rsa
+```
+
+Then, use this command to SSH to the EC2 Instance:
+
+```bash
+ssh jane@1.2.3.4
+```
+
+You should now be able to execute commands on the instance.
+
+## EC2 Key Pairs (For emergency / backup use only)
+
+When you launch an EC2 Instance in AWS, you can specify an EC2 Key Pair that can be used to SSH into the EC2 Instance. This suffers from an important problem: usually more than one person needs access to the EC2 Instance, which means you have to share this key with others. Sharing secrets of this sort is a security risk. Moreover, if someone leaves the company, to ensure they no longer have access, you'd have to change the Key Pair, which requires redeploying all of your servers.
+
+As part of the Reference Architecture deployment, Gruntwork will create EC2 Key Pairs and put the private keys into AWS Secrets Manager. These keys are there only for emergency / backup use: e.g., if there's a bug in `ssh-grunt` that prevents you from accessing your EC2 instances. We recommend only giving a handful of trusted admins access to these Key Pairs.
diff --git a/docs/refarch/access/how-to-auth-vpn/index.md b/docs/refarch/access/how-to-auth-vpn/index.md
index 13ac872ae9..0535cfe201 100644
--- a/docs/refarch/access/how-to-auth-vpn/index.md
+++ b/docs/refarch/access/how-to-auth-vpn/index.md
@@ -1,17 +1,51 @@
-# VPN Authentcation
+# VPN Authentication
+Most of the AWS resources that comprise the Reference Architecture run in private subnets, which means they do not have a public IP address, and cannot be reached directly from the public Internet. This reduces the "surface area" that attackers can reach. Of course, you still need access into the VPCs so we exposed a single entrypoint into the network: an [OpenVPN server](https://openvpn.net/).
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
+## Install an OpenVPN client
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
+There are free and paid OpenVPN clients available for most major operating systems. Popular options include:
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
+1. OS X: [Viscosity](https://www.sparklabs.com/viscosity/) or [Tunnelblick](https://tunnelblick.net/).
+1. Windows: [official client](https://openvpn.net/index.php/open-source/downloads.html).
+1. Linux:
+ ```bash title="Debian"
+ apt-get install openvpn
+ ```
+
+ ```bash title="Redhat"
+ yum install openvpn
+ ```
+
+## Join the OpenVPN IAM Group
+
+Your IAM User needs access to SQS queues used by the OpenVPN server. Since IAM users are defined only in the security account, and the OpenVPN servers are defined in separate AWS accounts (stage, prod, etc), that means you need to authenticate to the accounts with the OpenVPN servers by assuming an IAM Role that has access to the SQS queues in those accounts.
+
+To be able to assume an IAM Role, your IAM user needs to be part of an IAM Group with the proper permissions, such as `_account.xxx-full-access` or `_account.xxx-openvpn-users`, where `xxx` is the name of the account you want to access (stage, prod, etc). See [Configure other IAM users](/refarch/access/setup-auth/#configure-other-iam-users) for instructions on adding users to IAM Groups.
+
+## Use openvpn-admin to generate a configuration file
+
+To connect to an OpenVPN server, you need an OpenVPN configuration file, which includes a certificate that you can use to authenticate. To generate this configuration file, do the following:
+
+1. Install the latest [`openvpn-admin binary`](https://github.com/gruntwork-io/terraform-aws-openvpn/releases) for your OS.
+
+1. Authenticate to AWS via the CLI. You will need to assume an IAM Role in the AWS account with the OpenVPN server you're trying to connect to. This IAM Role must have access to the SQS queues used by OpenVPN server. Typically, the `allow-full-access-from-other-accounts` or `openvpn-server-allow-certificate-requests-for-external-accounts` IAM Role is what you want.
+
+1. Run `openvpn-admin request --aws-region --username `.
+
+1. This will create your OpenVPN configuration file in your current directory.
+
+1. Load this configuration file into your OpenVPN client.
+
+## Connect to one of your OpenVPN servers
+
+To connect to an OpenVPN server in one of your app accounts (Dev, Stage, Prod), click the "Connect" button next to your configuration file in the OpenVPN client. After a few seconds, you should be connected. You will now be able to access all the resources within the AWS network (e.g., SSH to EC2 instances in private subnets) as if you were "in" the VPC itself.
diff --git a/docs/refarch/access/setup-auth/index.md b/docs/refarch/access/setup-auth/index.md
index cfc5a67892..ab1f94aafe 100644
--- a/docs/refarch/access/setup-auth/index.md
+++ b/docs/refarch/access/setup-auth/index.md
@@ -1,35 +1,131 @@
# Set up AWS Auth
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
+## Configure root users
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
+Each of your AWS accounts has a root user that you need to configure. When you created the child AWS accounts (dev, stage, prod, etc), you provided the root user's email address for each account; if you don't know what those email addresses were, you can log in to the root account (the parent of the AWS Organization) and go to the AWS Organizations Console to find them.
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
+Once you have the email addresses, you'll need the passwords. When you create child accounts in an AWS organization, AWS will not allow you to set the root password. In order to generate the root password:
-## 1. Configure root user
+1. Go to the AWS Console.
+1. If you had previously signed into some other AWS account as an IAM User, rather than a root user, click "Sign-in using root account credentials."
+1. Enter the email address of the root user.
+1. Click "Forgot your password" to reset the password.
+1. Check the email address associated with the root user account for a link you can use to create a new password.
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
+:::danger
+Please note that the root user account can do anything in your AWS account, bypassing the security restrictions you put in place, so you need to take extra care with protecting this account.
+:::
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
+We strongly recommend that when you reset the password for each account, you also:
-## 2. Configure your IAM users
+1. Use a strong password: preferably 30+ characters, randomly generated, and stored in a secrets manager.
+1. Enable Multi-Factor Auth (MFA): Follow [these instructions](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html#enable-virt-mfa-for-root) to enable MFA for the root user.
+ After this initial set up, you should _not_ use the root user account afterward except in very rare circumstances. (e.g., if you get locked out of your IAM User account and no one has permissions to reset your password). For day-to-day tasks, you should use an IAM User instead, as described in the next section.
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
+Please note that you'll have to repeat the process above of resetting the password and enabling MFA for every account in your organization: dev, stage, prod, shared, security, logs, and the root account.
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
+## Configure your IAM user
-## 3. Configure other IAM users
+The security account defines and manages all IAM Users. When deploying your Reference Architecture, Gruntwork creates an IAM User with admin permissions in the security account. The password for the IAM User is encrypted via PGP using [Keybase](https://keybase.io) (you'll need a free account) and is Base64-encoded.
-Haxx0r ipsum foo Trojan horse new all your base are belong to us ip error private shell fopen semaphore epoch char packet sniffer segfault gurfle bypass. Memory leak bubble sort injection leet malloc brute force double xss mega sudo mountain dew void echo win emacs linux piggyback bin. I'm compiling float bang case cat infinite loop Donald Knuth unix for /dev/null machine code then chown d00dz worm gnu crack packet bar eof while.
+To access the Terraform state containing the password, you need to already be authenticated to the account. Thus to get access to the initial admin IAM User, we will use the root user credentials. To do this, you can either:
-Lib void brute force bypass nak concurrently all your base are belong to us break leapfrog bit default packet sniffer Linus Torvalds. Man pages packet stack trace Starcraft Donald Knuth pwned worm hello world public giga frack gurfle. Irc fork malloc fopen script kiddies flood blob fail hexadecimal while access semaphore loop mega Trojan horse foo gobble.
+- Log in to the AWS Web Console using the root user credentials for the security account and set up the password and AWS Access Keys for the IAM User.
-Bang spoof *.* headers Dennis Ritchie pragma bubble sort mutex d00dz firewall wombat snarf. Win L0phtCrack back door big-endian tera injection flush suitably small values interpreter class hello world client segfault. Boolean buffer emacs highjack concurrently boolean I'm compiling malloc finally char protected void fopen ascii var cd Trojan horse public.
+- Use the [Gruntwork CLI](https://github.com/gruntwork-io/gruntwork/) to rotate the password using the command:
+
+ ```bash
+ gruntwork aws reset-password --iam-user-name
+ ```
+
+Once you have access via your IAM user, finish hardening your security posture:
+
+1. Enable MFA for your IAM User by following [these instructions](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable.html). MFA is required by the Reference Architecture, and you won't be able to access any other accounts without it.
+
+ :::note
+ Note that the name of the MFA must be exactly the same as the AWS IAM Username
+ :::
+
+1. Log out and log back in — After enabling MFA, you need to log out and then log back in. This forces AWS to prompt you for your MFA token.
+
+ :::caution
+ Until you enable MFA, you will not be able to access anything else in the web console.
+ :::
+
+1. Create access keys for yourself by following [these instructions](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html). Store the access keys in a secrets manager. You will need these to authenticate to AWS from the command-line.
+
+## Configure other IAM users
+
+Now that your IAM user is all set up, you can configure IAM users for the rest of your team.
+
+:::note
+Each of your users will need a free [Keybase](https://keybase.io/) account so that their credentials can be encrypted just for their access.
+:::
+
+All of the IAM users are managed as code in the security account in the `account-baseline-app` module. If you open the `terragrunt.hcl` file in that repo, you should see the list of users, which will look something like:
+
+```yaml
+jane@acme.com:
+ create_access_keys: false
+ create_login_profile: true
+ groups:
+ - full-access
+ pgp_key: keybase:jane_on_keybase
+```
+
+Here's how you would add two more users, Alice and Bob, to your security account:
+
+```yaml
+jane@acme.com:
+ create_login_profile: true
+ groups:
+ - full-access
+ pgp_key: keybase:jane_on_keybase
+alice@acme.com:
+ create_login_profile: true
+ groups:
+ - _account.dev-full-access
+ - _account.stage-full-access
+ - _account.prod-full-access
+ - iam-user-self-mgmt
+ pgp_key: keybase:alice_on_keybase
+bob@acme.com:
+ create_login_profile: true
+ groups:
+ - _account.prod-read-only
+ - ssh-grunt-sudo-users
+ - iam-user-self-mgmt
+ pgp_key: keybase:bob_on_keybase
+```
+
+A few notes about the code above:
+
+1. **Groups**. We add each user to a set of IAM Groups: for example, we add Alice to IAM Groups that give her admin access in the dev, stage, and prod accounts, whereas Bob gets read-only access to prod, plus SSH access (with `sudo` permissions) to EC2 instances. For the full list of IAM Groups available, see the [IAM Groups module](https://github.com/gruntwork-io/terraform-aws-security/tree/main/modules/iam-groups#iam-groups).
+
+1. **PGP Keys**. We specify a PGP Key to use to encrypt any secrets for that user. Keys of the form `keybase:` are automatically fetched for user `` on [Keybase](https://keybase.io/).
+
+1. **Credentials**. For each user whose `create_login_profile` field is set to `true`, a password will be automatically generated. This password can be used to log in to the web console. This password will be encrypted with the user's PGP key and visible as a Terraform output. After you run `terragrunt apply`, you can copy/paste these encrypted credentials and send them to the user.
+
+To deploy this new code and create the new IAM Users, you will need to:
+
+1. Authenticate to AWS via the CLI.
+
+1. Apply your changes by running `terragrunt apply`.
+
+1. Share the login URL, usernames, and (encrypted) password with your team members.
+
+ :::note
+ Make sure to tell each team member to follow the [Configure your IAM User instructions](#configure-your-iam-user) to log in, reset their password, and enable MFA.
+ :::
+
+ :::caution
+ Enabling MFA is required to access the Reference Architecture
+ :::
diff --git a/sidebars/refarch.js b/sidebars/refarch.js
index 0c876b9c56..cb9af81a2d 100644
--- a/sidebars/refarch.js
+++ b/sidebars/refarch.js
@@ -15,8 +15,8 @@ const sidebar = [
collapsible: false,
items: [
"refarch/whats-this/what-is-a-reference-architecture",
- "refarch/whats-this/understanding-the-deployment-process"
- ]
+ "refarch/whats-this/understanding-the-deployment-process",
+ ],
},
{
label: "Configuration",
@@ -36,6 +36,8 @@ const sidebar = [
items: [
"refarch/access/setup-auth/index",
"refarch/access/how-to-auth-vpn/index",
+ "refarch/access/how-to-auth-aws-web-console/index",
+ "refarch/access/how-to-auth-CLI/index",
"refarch/access/how-to-auth-ec2/index",
],
},