Skip to content
This repository has been archived by the owner on Jan 8, 2024. It is now read-only.

Added a WrappedTokenUnsealer - fixes #8 #10

Merged
merged 1 commit into from
Jul 19, 2016
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ VGM also supports the client environment variables used by vault such as, `VAULT

`CUBBY_PATH` | `-cubby-path` - Path to key in cubbyhole. By default this is `/vault-token`.

`WRAPPED_TOKEN_AUTH` | `-wrapped-token-auth` - Temporary vault authorization token that has a wrapped permanent vault token.

`APP_ID` | `-auth-appid` - Use the `app-id` authorization method with this app id.

`USER_ID_METHOD` | `-auth-userid-method` - With the `app-id` authorization method, this argument decides how VGM should generate the user id. Valid values are `mac` and `file`.
Expand Down
27 changes: 19 additions & 8 deletions gatekeeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@ var config struct {
CaPath string
GkPolicies string
}
SelfRecreate bool
ListenAddress string
TlsCert string
TlsKey string
Mesos string
MaxTaskLife time.Duration
AppIdAuth AppIdUnsealer
CubbyAuth CubbyUnsealer
SelfRecreate bool
ListenAddress string
TlsCert string
TlsKey string
Mesos string
MaxTaskLife time.Duration
AppIdAuth AppIdUnsealer
CubbyAuth CubbyUnsealer
WrappedTokenAuth WrappedTokenUnsealer
}

var state struct {
Expand Down Expand Up @@ -88,6 +89,8 @@ func init() {
flag.StringVar(&config.CubbyAuth.TempToken, "cubby-token", defaultEnvVar("CUBBY_TOKEN", ""), "Temporary vault authorization token that has a cubbyhole secret in CUBBY_PATH that contains the permanent vault token.")
flag.StringVar(&config.CubbyAuth.Path, "cubby-path", defaultEnvVar("CUBBY_PATH", "/vault-token"), "Path to key in cubbyhole. By default this is /vault-token.")

flag.StringVar(&config.WrappedTokenAuth.TempToken, "wrapped-token-auth", defaultEnvVar("WRAPPED_TOKEN_AUTH", ""), "Temporary vault authorization token that has a wrapped permanent vault token.")

flag.StringVar(&config.AppIdAuth.AppId, "auth-appid", defaultEnvVar("APP_ID", ""), "Vault App Id for authenication. (Overrides the APP_ID environment variable if set.)")
flag.StringVar(&config.AppIdAuth.UserIdMethod, "auth-userid-method", defaultEnvVar("USER_ID_METHOD", ""), "Vault User Id authenication method (either 'mac' or 'file'). (Overrides the USER_ID_METHOD environment variable if set.)")
flag.StringVar(&config.AppIdAuth.UserIdInterface, "auth-userid-interface", defaultEnvVar("USER_ID_INTERFACE", ""), "Network interface for 'mac' user id authenication method. (Overrides the USER_ID_INTERFACE environment variable if set.)")
Expand Down Expand Up @@ -342,6 +345,14 @@ func main() {
os.Exit(1)
}
log.Println("Unseal successful with token provided by Cubbyhole.")
} else if config.WrappedTokenAuth.TempToken != "" {
log.Println("Attempting to unseal with Wrapped Token...")
if err := unseal(config.WrappedTokenAuth); err != nil {
log.Println("Failed to unseal using Wrapped Token. Please make sure the Wrapped Token auth is correctly setup.")
log.Println("Error:", err)
os.Exit(1)
}
log.Println("Unseal successful with Wrapped Token.")
} else if config.AppIdAuth.AppId != "" {
log.Println("Attempting to unseal with provided APP ID credentials, using user_id from '" + config.AppIdAuth.UserIdMethod + "'...")
if err := unseal(config.AppIdAuth); err != nil {
Expand Down
10 changes: 10 additions & 0 deletions html.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ const htmlTemplateVal = `<!DOCTYPE html>
.active-form.active-cubby .visible-cubby {
display: block;
}
.active-form.active-wrapped-token .visible-wrapped-token {
display: block;
}
.status-unsealed {
display: {{.StatusUnsealed}};
}
Expand Down Expand Up @@ -85,6 +88,7 @@ const htmlTemplateVal = `<!DOCTYPE html>
<option value="github">GitHub</option>
<option value="userpass">Username &amp; Password</option>
<option value="cubby">Cubby Method</option>
<option value="wrapped-token">Wrapped Token Method</option>
<option value="token">Token</option>
</select>
</div>
Expand Down Expand Up @@ -150,6 +154,12 @@ const htmlTemplateVal = `<!DOCTYPE html>
<input type="password" class="form-control" id="cubby_path" name="cubby_path" placeholder="/vault-token">
</div>
</div>
<div class="form-section visible-wrapped-token">
<div class="form-group">
<label for="wrapped_token">Wrapped Token Method: Temp Token</label>
<input type="text" class="form-control" id="wrapped_token" name="wrapped_token">
</div>
</div>
<div class="text-right">
<button type="submit" class="btn btn-primary text-right">Unseal</button>
</div>
Expand Down
6 changes: 6 additions & 0 deletions routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ func Unseal(c *gin.Context) {
case "cubby":
request.Token = c.Request.FormValue("cubby_token")
request.CubbyPath = c.Request.FormValue("cubby_path")
case "wrapped-token":
request.Token = c.Request.FormValue("wrapped_token")
default:
c.JSON(400, struct {
Status string `json:"status"`
Expand Down Expand Up @@ -140,6 +142,10 @@ func Unseal(c *gin.Context) {
TempToken: request.Token,
Path: request.CubbyPath,
}
case "wrapped-token":
unsealer = WrappedTokenUnsealer{
TempToken: request.Token,
}
default:
c.JSON(400, struct {
Status string `json:"status"`
Expand Down
56 changes: 56 additions & 0 deletions unsealer.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,3 +270,59 @@ func (t CubbyUnsealer) Token() (string, error) {
func (t CubbyUnsealer) Name() string {
return "cubby"
}

type WrappedTokenUnsealer struct {
TempToken string
}

var errInvalidWrappedToken = errors.New("Invalid wrapped token.")

func (t WrappedTokenUnsealer) Token() (string, error) {
resp, err := VaultRequest{
goreq.Request{
Uri: vaultPath("/v1/cubbyhole/response", ""),
MaxRedirects: 10,
RedirectHeaders: true,
}.WithHeader("X-Vault-Token", t.TempToken),
}.Do()
if err != nil {
return "", err
}
defer resp.Body.Close()

if resp.StatusCode != 200 {
var e vaultError
e.Code = resp.StatusCode

if err := resp.Body.FromJsonTo(&e); err != nil {
e.Errors = []string{"communication error."}
return "", e

}

return "", e
}

vaultWrappedResp := struct {
Data struct {
WrappedSecret struct {
Token string `json:"token"`
} `json:"response"`
} `json:"data"`
}{}

if err := resp.Body.FromJsonTo(&vaultWrappedResp); err != nil {
return "", err

}

if vaultWrappedResp.Data.WrappedSecret.Token == "" {
return "", errInvalidWrappedToken
}

return TokenUnsealer{vaultWrappedResp.Data.WrappedSecret.Token}.Token()
}

func (t WrappedTokenUnsealer) Name() string {
return "wrapped-token"
}