-
Notifications
You must be signed in to change notification settings - Fork 153
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generate S3 server credentials on-the-fly
To improve the security of GitOps Run we now generate access and secret keys each time the `gitops beta run` command is run. These credentials are passed on to the S3 server and used in the client code for authentication.
- Loading branch information
Showing
9 changed files
with
210 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package s3 | ||
|
||
import ( | ||
"crypto/rand" | ||
"fmt" | ||
"io" | ||
"math/big" | ||
) | ||
|
||
type RandIntFunc func(io.Reader, *big.Int) (*big.Int, error) | ||
|
||
var DefaultRandIntFunc = rand.Int | ||
|
||
const ( | ||
numRandomCharsInAccessKey = 10 | ||
numRandomCharsInSecretKey = 40 | ||
) | ||
|
||
var ( | ||
accessKeyLetters = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") | ||
secretKeyLetters = []rune("abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") | ||
) | ||
|
||
func GenerateAccessKey(randInt RandIntFunc) ([]byte, error) { | ||
accessKey, err := generateRandomKey(randInt, numRandomCharsInAccessKey, accessKeyLetters) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return []byte("AKIA" + string(accessKey)), nil | ||
} | ||
|
||
func GenerateSecretKey(randInt RandIntFunc) ([]byte, error) { | ||
return generateRandomKey(randInt, numRandomCharsInSecretKey, secretKeyLetters) | ||
} | ||
|
||
func generateRandomKey(randInt RandIntFunc, numChars int, letters []rune) ([]byte, error) { | ||
key := make([]rune, numChars) | ||
|
||
for i := range key { | ||
num, err := randInt(rand.Reader, big.NewInt(int64(len(letters)))) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to get random number: %w", err) | ||
} | ||
|
||
key[i] = letters[num.Int64()] | ||
} | ||
|
||
return []byte(string(key)), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package s3 | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"math/big" | ||
"math/rand" | ||
"testing" | ||
|
||
. "github.com/onsi/gomega" | ||
) | ||
|
||
func deterministicRandInt(seed int64, err error) RandIntFunc { | ||
seeded := false | ||
|
||
return func(_ io.Reader, max *big.Int) (*big.Int, error) { | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if !seeded { | ||
rand.Seed(seed) | ||
|
||
seeded = true | ||
} | ||
|
||
return big.NewInt(int64(rand.Intn(int(max.Int64())))), nil | ||
} | ||
} | ||
|
||
func TestGenerators(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
generator func(RandIntFunc) ([]byte, error) | ||
randIntFunc RandIntFunc | ||
expected string | ||
expectedErr bool | ||
}{ | ||
{ | ||
name: "GenerateAccessKey generates a deterministic access key", | ||
generator: GenerateAccessKey, | ||
randIntFunc: deterministicRandInt(100, nil), | ||
expected: "AKIA5UQA4UZJM3", | ||
expectedErr: false, | ||
}, | ||
{ | ||
name: "GenerateAccessKey properly returns an error if RNG fails", | ||
generator: GenerateAccessKey, | ||
randIntFunc: deterministicRandInt(0, fmt.Errorf("foobar")), | ||
expected: "", | ||
expectedErr: true, | ||
}, | ||
{ | ||
name: "GenerateSecretKey generates a deterministic secret key", | ||
generator: GenerateSecretKey, | ||
randIntFunc: deterministicRandInt(512, nil), | ||
expected: "Fg5n9W6CwTfnMu4FzEk8xuTomwk2OpFe0yLcLMAL", | ||
expectedErr: false, | ||
}, | ||
{ | ||
name: "GenerateSecretKey properly returns an error if RNG fails", | ||
generator: GenerateSecretKey, | ||
randIntFunc: deterministicRandInt(0, fmt.Errorf("foobar")), | ||
expected: "", | ||
expectedErr: true, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
g := NewGomegaWithT(t) | ||
|
||
accessKey, err := tt.generator(tt.randIntFunc) | ||
if tt.expectedErr { | ||
g.Expect(err).To(HaveOccurred()) | ||
} else { | ||
g.Expect(err).NotTo(HaveOccurred()) | ||
} | ||
g.Expect(string(accessKey)).To(Equal(tt.expected)) | ||
}) | ||
} | ||
} |