Skip to content

Commit

Permalink
Merge pull request #9 from tonedefdev/rc-2.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
tonedefdev authored Oct 24, 2021
2 parents 44e14f8 + 7fc06a0 commit 982e416
Show file tree
Hide file tree
Showing 21 changed files with 1,711 additions and 175 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@

# Dependency directories (remove the comment below to include it)
# vendor/

terraform/.terraform/*
terraform/.terraform.tfstate.lock.info
terraform/terraform.tfstate
terraform/terraform.tfstate.backup
terracreds
96 changes: 89 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<img src="https://github.com/tonedefdev/terracreds/blob/main/img/terracreds.png?raw=true" align="right" width="350" height="350">

# Terracreds
A credential helper for Terraform Cloud/Enterprise that allows secure storage of your API token within the operating system's vault instead of in a plain text configuration file
A credential helper for Terraform Cloud/Enterprise, or to store other secrets, securely in the operating system's credential vault or through a third party vault. No longer keep secrets in a plain text configuration file!

We all know storing secrets in plain text can pose major security threats, and Terraform doesn't come pre-packaged with a credential helper, so we decided to create one and to share it with the greater Terraform/DevOps community to help enable stronger security practices

Expand All @@ -12,10 +12,16 @@ We all know storing secrets in plain text can pose major security threats, and T
- [x] MacOS (Keychain)
- [x] Linux (gnome-keyring) *Tested on Ubuntu 20.04*

#### Currently supported Vault providers:
- [x] AWS Secrets Manager
- [x] Azure Key Vault
- [ ] Google Secret Manager
- [x] HashiCorp Vault

## Windows Install via Chocolatey
The fastest way to install `terracreds` on Windows is via our Chocolatey package:
```powershell
choco install terracreds -y
choco install terracreds --version "2.0.0" -y
```

Once installed run the following command to verify `terracreds` was installed properly:
Expand All @@ -25,7 +31,7 @@ terracreds -v

To upgrade `terracreds` to the latest version with Chocolatey run the the following command:
```powershell
choco upgrade terracreds -y
choco upgrade terracreds --version "2.0.0" -y
```

## macOS Install
Expand All @@ -36,10 +42,10 @@ extract the package, and then place it in a directory available on `$HOME`
You'll need to download the latest binary from our release page and place it anywhere on `$PATH` of your system. You can also copy and run the following commands:

```bash
wget https://github.com/tonedefdev/terracreds/releases/download/v1.1.1/terracreds_1.1.1_linux_amd64.tar.gz && \
tar -xvf terracreds_1.1.1_linux_amd64.tar.gz && \
wget https://github.com/tonedefdev/terracreds/releases/download/v2.0.0/terracreds_2.0.0_linux_amd64.tar.gz && \
tar -xvf terracreds_2.0.0_linux_amd64.tar.gz && \
sudo mv -f terracreds /usr/bin/terracreds && \
rm -f terracreds_1.1.1_linux_amd64.tar.gz README.md
rm -f terracreds_2.0.0_linux_amd64.tar.gz README.md
```

The `terracreds` Linux implementation uses `gnome-keyring` in conjunction with `gnome-keyring-daemon`
Expand Down Expand Up @@ -179,8 +185,84 @@ Success! Terraform has removed the stored API token for app.terraform.io.

Additionally, you can check the `terracreds.log` if logging is enabled for more information

## Setting Up a Vault Provider
> You can reference example configs in our [repo](https://github.com/tonedefdev/terracreds/blob/main/config.yaml) plus we have example [terraform](https://github.com/tonedefdev/terracreds/tree/main/terraform) code you can reference in order to setup your `AWS` or `Azure` VMs to use `terracreds` for a CI/CD piepline agent or a development workstation
### AWS Secrets Manager
> Currently, we only support using an `EC2 Instance Role` for authentication. This ensures the highest level of security by alleviating the `secret zero` dilemma
In order to leverage `terracreds` to manage secrets in `AWS Secrets Manager` the following block needs to be provided in the configuration file:
```yaml
aws:
description: my_terraform_api_token
region: us-west-2
secretName: my-secret-name
```
| Value | Description | Required |
| ----- | ----------- | -------- |
| `description` | A brief description to provide for the secret object viewable in `Secrets Manager` | `yes` |
| `region` | The `Secrets Manager` instance's region where the secret will be stored | `yes` |
| `secretName` | A name for the secret. If omitted and using `terraform login` the hostname of the TFC\TFE server will be used for the name instead | `no` |

The following role permissions are required in order for the `EC2 Instance Role` to levearge `terracreds` with `AWS Secrets Manager`:
```hcl
Action = [
"secretsmanager:CreateSecret",
"secretsmanager:DeleteSecret",
"secretsmanager:GetSecretValue",
"secretsmanager:PutSecretValue"
]
```
### Azure Key Vault
> Currently, we only support using a `Managed Service Identity` for authentication. This ensures the highest level of security by alleviating the `secret zero` dilemma

In order to leverage `terracreds` to manage secrets in `Azure Key Vault` the following block needs to be provided in the configuration file:
```yaml
azure:
secretName: my-secret-name
useMSI: true
vaultUri: https://keyvault.azure.net
```

| Value | Description | Required |
| ----- | ----------- | -------- |
| `secretName` | A name for the secret. If omitted and using `terraform login` the hostname of the TFC\TFE server will be used for the name instead | `no` |
| `useMSI` | A flag to choose whether or not to use `Manged Service Identity`. Currently, `true` is required | `yes` |
| `vaultUri` | The URI for the `Azure Key Vault` where you want to store or retrieve your credentials | `yes` |

The following `Azure Key Vault Access Policies` are required to be given to the `Managed Service Identity` for it to leverage `terracreds`:
```hcl
secret_permissions = [
"Get",
"List",
"Set",
"Delete"
]
```
> Since `Azure Key Vault` doesn't support the period character in a secret name a helper function will replace any periods with dashes so they can be successfully stored. This means a `terraform` API token name that would usually be `app.terraform.io` will become `app-terraform-io`

### HashiCorp Vault
In order to leverage `terracreds` to manage secrets in `HashiCorp Vault` the following block needs to be provided in the configuration file:
```yaml
hcvault:
environmentTokenName: HASHI_TOKEN
keyVaultPath: kv
secretName: my-secret-name
secretPath: tfe
vaultUri: http://localhost:8200
```

| Value | Description | Required |
| ----- | ----------- | -------- |
| `environmentTokenName` | The name of the environment variable that contains the token value to authenticate with `HashiCorp Vault` | `yes` |
| `keyVaultPath` | The path to the `Key Vault` object within the vault | `yes` |
| `secretName` | A name for the secret. If omitted and using `terraform login` the hostname of the TFC\TFE server will be used for the name instead | `no` |
| `secretPath` | The path of the secret within `HashiCorp Vault` | `yes` |
| `vaultUri` | The URI for the `HashiCorp Vault` instance | `yes` |

## Protection
In order to add some protection `terracreds` adds a username to the credential object, and checks to ensure that the user requesting access to the token is the same user as the token's creator. This means that only the user account used to create the token can view the token from `terracreds` which ensures that the token can only be read by the account used to create it. Any attempt to access or modify this token from `terracreds` outside of the user that created the credentail will lead to denial messages. Additionally, if the credential name is not found, the same access denied message will be provided in lieu of a generic not found message to help prevent brute force attempts
In order to add some protection `terracreds` adds a username to the credential object to secrets stored in the local operating system, and checks to ensure that the user requesting access to the token is the same user as the token's creator. This means that only the user account used to create the token can view the token from `terracreds` which ensures that the token can only be read by the account used to create it. Any attempt to access or modify this token from `terracreds` outside of the user that created the credentail will lead to denial messages. Additionally, if the credential name is not found, the same access denied message will be provided in lieu of a generic not found message to help prevent brute force attempts

## Logging
Wherever either binary is stored `terracreds` or `terraform-credential-terracreds` a `config.yaml` file is generated on first launch of the binary. Currently, this configuration file only enables/disables logging and sets the log path. If logging is enabled you'll find the log named `terracreds.log` at the provided path
Expand Down
60 changes: 56 additions & 4 deletions api/api.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,63 @@
package api

// Aws is the configuration structure for the AWS vault provider
type Aws struct {
// Description (Optional) A description to provide to the secret
Description string `yaml:"description,omitempty"`

// Region (Required) The region where AWS Secrets Manager is hosted
Region string `yaml:"region,omitempty"`

// SecretName (Optional) The friendly name of the secret stored in AWS Secrets Manager
// if omitted Terracreds will use the hostname value instead
SecretName string `yaml:"secretName,omitempty"`
}

// Azure is the configuration structure for the Azure vault provider
type Azure struct {
// SecretName (Optional) The name of the secret stored in Azure Key Vault
// if omitted Terracreds will use the hostname value instead
SecretName string `yaml:"secretName,omitempty"`

// UseMSI (Required) A flag to indicate if the Managed Identity of the Azure VM should be used for authentication
UseMSI bool `yaml:"useMSI,omitempty"`

// VaultUri (Required) The FQDN of the Azure Key Vault resource
VaultUri string `yaml:"vaultUri,omitempty"`
}

// HCVault is the configuration structure for the Hashicorp Vault provider
type HCVault struct {
// EnvironmentTokenName (Required) The name of the environment variable that currently holds
// the Vault token
EnvironmentTokenName string `yaml:"environmentTokenName,omitempty"`

// KeyVaultPath (Required) The name of the Key Vault store inside of Vault
KeyVaultPath string `yaml:"keyVaultPath,omitempty"`

// SecretName (Optional) The name of the secret stored inside of Vault
// if omitted Terracreds will use the hostname value instead
SecretName string `yaml:"secretName,omitempty"`

// SecretPath (Required) The path to the secret itself inside of Vault
SecretPath string `yaml:"secretPath,omitempty"`

// VaultUri (Required) The URL of the Vault instance including its port
VaultUri string `yaml:"vaultUri,omitempty"`
}

// Config struct for terracreds custom configuration
type Config struct {
Logging struct {
Enabled bool `yaml:"enabled"`
Path string `yaml:"path"`
} `yaml:"logging"`
Logging Logging `yaml:"logging"`
Aws Aws `yaml:"aws,omitempty"`
Azure Azure `yaml:"azure,omitempty"`
HashiVault HCVault `yaml:"hcvault,omitempty"`
}

// Logging struct defines the parameters for logging
type Logging struct {
Enabled bool `yaml:"enabled"`
Path string `yaml:"path"`
}

// CredentialResponse formatted for consumption by Terraform
Expand Down
17 changes: 17 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
logging:
enabled: true
path: C:/temp/
aws:
description: my_secret_name
region: us-west-2
secretName: my-secret
azure:
secretName: my-secret-name
useMSI: true
vaultUri: https://keyvault.azure.net
hcvault:
environmentTokenName: HASHI_TOKEN
keyVaultPath: kv
secretName: something-dumb
secretPath: tfe
vaultUri: http://localhost:8200
11 changes: 7 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ module github.com/tonedefdev/terracreds
go 1.15

require (
github.com/Azure/azure-sdk-for-go v58.1.0+incompatible
github.com/Azure/go-autorest/autorest/azure/auth v0.5.8
github.com/Azure/go-autorest/autorest/to v0.4.0
github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
github.com/MakeNowJust/heredoc v1.0.0
github.com/aws/aws-sdk-go v1.41.0
github.com/danieljoos/wincred v1.1.0
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.9.0
github.com/kr/pretty v0.1.0 // indirect
github.com/stretchr/objx v0.1.1 // indirect
github.com/google/go-cmp v0.5.6 // indirect
github.com/hashicorp/vault/api v1.1.1
github.com/urfave/cli/v2 v2.2.0
github.com/zalando/go-keyring v0.1.0
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/yaml.v2 v2.3.0
)
Loading

0 comments on commit 982e416

Please sign in to comment.