Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Docker entry-point: decrypt-and-start #1

Merged
merged 1 commit into from Jul 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -10,3 +10,6 @@

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# output binary
decrypt-and-start
17 changes: 17 additions & 0 deletions README.md
@@ -0,0 +1,17 @@
# decrypt-and-start

This project began as a shell script to invoke the `kms-encryption decrypt`
on the variables in the environment, looking for anything with a prefix of
"decrypt:", decrypting it using AWS KMS using the instance's profile, and
exporting the decrypted value back to the environment before exec to the
next command.

This is used as a Docker entrypoint for containers to be able to decrypt
encrypted environment variables passed into it.

## Usage

This project is a replacement for the ApplauseOSS/kms-encryption-toolbox
supplied shell script, `decrypt-and-start`.


7 changes: 7 additions & 0 deletions ci/build.sh
@@ -0,0 +1,7 @@
#!/bin/bash

# Assumes go is installed

go get ./...

go build
4 changes: 4 additions & 0 deletions ci/test.sh
@@ -0,0 +1,4 @@
#!/bin/bash

ENC_VAR=$(go run test/encrypt-string.go)
./decrypt-and-start env | grep ENV_VAR
66 changes: 66 additions & 0 deletions decrypt-and-start.go
@@ -0,0 +1,66 @@
package main

import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/kms"

"encoding/base64"
"flag"
"fmt"
"log"
"os"
"os/exec"
"strings"
"syscall"
)

// This function should work like an entrypoint: exec "${@}"
func Exec() {
flag.Parse()
if len(os.Args) == 1 {
return
}
cmd, err := exec.LookPath(os.Args[1])
if err != nil {
log.Fatal(err)
}
if err := syscall.Exec(cmd, flag.Args(), os.Environ()); err != nil {
log.Fatal(err)
}
}

func main() {
// Initialize a "fake" session to get our region
metaSession, _ := session.NewSession()
metaClient := ec2metadata.New(metaSession)
region, _ := metaClient.Region()
conf := aws.NewConfig().WithRegion(region)
// Initialize KMS session
sess := session.Must(session.NewSession(conf))
// KMS service client
svc := kms.New(sess)
for _, e := range os.Environ() {
// e = each k=v pair/line, pair = split k = [0], v = [1] array
pair := strings.SplitN(e, "=", 2)
// See if value starts with 'decrypt:'
if strings.HasPrefix(pair[1], "decrypt:") {
fmt.Println("Decrypting " + pair[0] + " ...")
cyphertext, err := base64.URLEncoding.DecodeString(strings.TrimPrefix(pair[1], "decrypt:"))
if err != nil {
log.Fatal(err)
}
// blob := []byte(string(cyphertext))
blob := cyphertext
// decrypt data
result, err := svc.Decrypt(&kms.DecryptInput{CiphertextBlob: blob})
if err != nil {
log.Fatal(err)
}
decrypted_value := string(result.Plaintext)
os.Setenv(pair[0], decrypted_value)
}
}
Exec()
}
55 changes: 55 additions & 0 deletions test/encrypt-string.go
@@ -0,0 +1,55 @@
package main

import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/kms"

"encoding/base64"
"flag"
"fmt"
"log"
"os"
"os/exec"
// "strings"
"syscall"
)

// This function should work like an entrypoint: exec "${@}"
func Exec() {
flag.Parse()
if len(os.Args) == 1 {
return
}
cmd, err := exec.LookPath(os.Args[1])
if err != nil {
log.Fatal(err)
}
if err := syscall.Exec(cmd, flag.Args(), os.Environ()); err != nil {
log.Fatal(err)
}
}

func main() {
// Initialize KMS session
// sess := session.Must(session.NewSessionWithOptions(session.Options{
// SharedConfigState: session.SharedConfigEnable,
// }))
sess := session.Must(session.NewSession(&aws.Config{
Region: aws.String("us-east-1"),
}))
cmk_arn := "arn:aws:kms:us-east-1:873559269338:key/1b03c937-31f8-4fa5-a5cf-42e9f437bda2"
// KMS service client
svc := kms.New(sess)

text := "some-encrypted-string"

result, err := svc.Encrypt(&kms.EncryptInput{
KeyId: aws.String(cmk_arn),
Plaintext: []byte(text),
})
if err != nil {
log.Fatal(err)
}
fmt.Println(base64.URLEncoding.EncodeToString(result.CiphertextBlob))
}