Skip to content

Commit

Permalink
Add support for durations in config (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kristian Dalmo Olsen authored Dec 9, 2020
1 parent 082461e commit 9209d00
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 40 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ requests:
name: open-source-dev-read-only
config:
role_arn: arn:aws:iam::role/role-name
duration: 900
duration: 15m
- store: secretsmanager
creds:
- type: github:access-token
Expand Down
42 changes: 21 additions & 21 deletions cmd/sidecred/testdata/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,25 @@ stores:
- type: ssm

requests:
- store: ssm
- store: ssm
creds:
- type: aws:sts
name: open-source-dev-read-only
config:
role_arn: arn:aws:iam::role/role-name
duration: 900
- type: github:access-token
name: itsdalmo-access-token
config:
owner: itsdalmo
repositories:
- dotfiles
permissions:
contents: read
- type: github:deploy-key
name: dotfiles-deploy-key
config:
title: sidecred-test
owner: itsdalmo
repository: dotfiles
read_only: true
- type: aws:sts
name: open-source-dev-read-only
config:
role_arn: arn:aws:iam::role/role-name
duration: 15m
- type: github:access-token
name: itsdalmo-access-token
config:
owner: itsdalmo
repositories:
- dotfiles
permissions:
contents: read
- type: github:deploy-key
name: dotfiles-deploy-key
config:
title: sidecred-test
owner: itsdalmo
repository: dotfiles
read_only: true
8 changes: 4 additions & 4 deletions config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ requests:
name: open-source-dev-read-only
config:
role_arn: arn:aws:iam::role/role-name
duration: 900
duration: 15m
`),
expected: "",
expectedRequestCount: 1,
Expand All @@ -60,7 +60,7 @@ requests:
- name: open-source-dev-read-only
config:
role_arn: arn:aws:iam::role/role-name
duration: 900
duration: 15m
`),
expected: "",
expectedRequestCount: 1,
Expand All @@ -86,7 +86,7 @@ requests:
- name: open-source-dev-read-only
config:
role_arn: arn:aws:iam::role/role-name
duration: 900
duration: 15m
`),
expected: "",
expectedRequestCount: 1,
Expand All @@ -110,7 +110,7 @@ requests:
name: open-source-dev-read-only
config:
role_arn: arn:aws:iam::role/role-name
duration: 900
duration: 15m
- type: aws:sts
name: open-source-dev-read-only
`),
Expand Down
6 changes: 3 additions & 3 deletions provider/artifactory/artifactory.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ type RequestConfig struct {
Group string `json:"group"`

// Request-specific override for credential duration.
Duration int `json:"duration"`
Duration *sidecred.Duration `json:"duration"`
}

// NewClient returns a new client for ArtifactoryAPI.
Expand Down Expand Up @@ -123,8 +123,8 @@ func (p *provider) Create(request *sidecred.CredentialRequest) ([]*sidecred.Cred
return nil, nil, err
}
duration := int(p.sessionDuration.Seconds())
if c.Duration != 0 {
duration = c.Duration
if c.Duration != nil {
duration = int(c.Duration.Seconds())
}

params := services.CreateTokenParams{
Expand Down
2 changes: 1 addition & 1 deletion provider/artifactory/artifactory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func TestArtifactoryProvider(t *testing.T) {
request: &sidecred.CredentialRequest{
Type: sidecred.AWSSTS,
Name: "request-name",
Config: []byte(`{"user": "some-user", "group": "some-artifactory-group", "duration": 60}`),
Config: []byte(`{"user": "some-user", "group": "some-artifactory-group", "duration": "60s"}`),
},
},
}
Expand Down
8 changes: 4 additions & 4 deletions provider/sts/sts.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import (

// RequestConfig ...
type RequestConfig struct {
RoleARN string `json:"role_arn"`
Duration int64 `json:"duration"`
RoleARN string `json:"role_arn"`
Duration *sidecred.Duration `json:"duration"`
}

// NewClient returns a new client for STSAPI.
Expand Down Expand Up @@ -70,8 +70,8 @@ func (p *provider) Create(request *sidecred.CredentialRequest) ([]*sidecred.Cred
return nil, nil, err
}
duration := int64(p.sessionDuration.Seconds())
if c.Duration != 0 {
duration = c.Duration
if c.Duration != nil {
duration = int64(c.Duration.Seconds())
}
input := &sts.AssumeRoleInput{
RoleSessionName: aws.String(request.Name),
Expand Down
2 changes: 1 addition & 1 deletion provider/sts/sts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func TestSTSProvider(t *testing.T) {
request: &sidecred.CredentialRequest{
Type: sidecred.AWSSTS,
Name: "request-name",
Config: []byte(`{"role_arn": "request-role-arn", "duration":60}`),
Config: []byte(`{"role_arn": "request-role-arn", "duration":"60s"}`),
},
},
}
Expand Down
31 changes: 28 additions & 3 deletions sidecred.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package sidecred
import (
"encoding/json"
"fmt"
"strconv"
"strings"
"text/template"
"time"
Expand All @@ -24,7 +25,7 @@ type CredentialRequest struct {
// measured in seconds.
// This will aid in cases where we want to be more granular
// for possibly longer running authentications or processes.
RotationWindow int `json:"rotation_window"`
RotationWindow *Duration `json:"rotation_window"`

// Config holds the specific configuration for the requested credential
// type, and must be deserialized by the provider when Create is called.
Expand Down Expand Up @@ -54,8 +55,8 @@ func (r *CredentialRequest) hasValidCredentials(resource *Resource, rotationWind
}

rotation := rotationWindow
if r.RotationWindow != 0 {
rotation = time.Duration(r.RotationWindow) * time.Second
if r.RotationWindow != nil {
rotation = r.RotationWindow.Duration
}

if resource.Expiration.Add(-rotation).Before(time.Now()) {
Expand All @@ -65,6 +66,30 @@ func (r *CredentialRequest) hasValidCredentials(resource *Resource, rotationWind
return true
}

// Duration implements JSON (un)marshal for time.Duration.
type Duration struct {
time.Duration
}

// MarshalJSON implements json.Marshaler.
func (d Duration) MarshalJSON() ([]byte, error) {
return json.Marshal(d.String())
}

// UnmarshalJSON implements json.Unmarshaler.
func (d *Duration) UnmarshalJSON(data []byte) error {
s, err := strconv.Unquote(string(data))
if err != nil {
return err
}
v, err := time.ParseDuration(s)
if err != nil {
return fmt.Errorf("parse duration: %s", err)
}
d.Duration = v
return nil
}

// CredentialType ...
type CredentialType string

Expand Down
4 changes: 2 additions & 2 deletions sidecred_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ requests:
- store: inprocess
creds:
- type: random
rotation_window: 1800 # 30 minutes
rotation_window: 30m
name: fake.state.id
`),
resources: []*sidecred.Resource{{
Expand Down Expand Up @@ -168,7 +168,7 @@ requests:
- store: inprocess
creds:
- type: random
rotation_window: 240 # 4 minutes
rotation_window: 240s
name: fake.state.id
`),
resources: []*sidecred.Resource{{
Expand Down

0 comments on commit 9209d00

Please sign in to comment.