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

DynamoDB Watermark Backend #499

Merged
merged 7 commits into from
Oct 25, 2024
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
3 changes: 2 additions & 1 deletion cmd/approve-list-svc/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/ecadlabs/signatory/pkg/config"
"github.com/ecadlabs/signatory/pkg/hashmap"
"github.com/ecadlabs/signatory/pkg/signatory"
"github.com/ecadlabs/signatory/pkg/signatory/watermark"
"github.com/ecadlabs/signatory/pkg/vault"
"github.com/ecadlabs/signatory/pkg/vault/memory"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -57,7 +58,7 @@ func testServer(t *testing.T, addr []net.IP) error {

conf := signatory.Config{
Vaults: map[string]*config.VaultConfig{"mock": {Driver: "mock"}},
Watermark: signatory.IgnoreWatermark{},
Watermark: watermark.Ignore{},
VaultFactory: vault.FactoryFunc(func(ctx context.Context, name string, conf *yaml.Node) (vault.Vault, error) {
return memory.New([]*memory.PrivateKey{
{
Expand Down
11 changes: 6 additions & 5 deletions cmd/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/ecadlabs/signatory/pkg/config"
"github.com/ecadlabs/signatory/pkg/metrics"
"github.com/ecadlabs/signatory/pkg/signatory"
"github.com/ecadlabs/signatory/pkg/signatory/watermark"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -49,11 +50,11 @@ func NewRootCommand(c *Context, name string) *cobra.Command {
}
}

if baseDir == "" {
baseDir = conf.BaseDir
if baseDir != "" {
conf.BaseDir = baseDir
}
baseDir = os.ExpandEnv(baseDir)
if err := os.MkdirAll(baseDir, 0770); err != nil {
conf.BaseDir = os.ExpandEnv(conf.BaseDir)
if err := os.MkdirAll(conf.BaseDir, 0770); err != nil {
return err
}

Expand All @@ -78,7 +79,7 @@ func NewRootCommand(c *Context, name string) *cobra.Command {
return err
}

watermark, err := signatory.NewFileWatermark(baseDir)
watermark, err := watermark.Registry().New(cmd.Context(), conf.Watermark.Driver, &conf.Watermark.Config, conf)
if err != nil {
return err
}
Expand Down
5 changes: 1 addition & 4 deletions docs/aws_kms.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ vaults:
aws:
driver: awskms
config:
user_name: <iam_username>
access_key_id: <aws_access_key_id>
secret_access_key: <aws_secret_access_key>
region: <aws_region>
Expand All @@ -29,7 +28,6 @@ vaults:

Name | Type | Required | Description
-----|------|:--------:|------------
user_name | string |✅| IAM user name
access_key_id | string | OPTIONAL | IAM user detail
secret_access_key | string | OPTIONAL | IAM user detail
region | string | ✅ | Region where key is created
Expand All @@ -54,7 +52,7 @@ To generate a new private key withing AWS, you must:

## Example Configuration for the AWS KMS vault in Signatory

This example shows a Signatory vault configuration for AWS KMS. Text in `{}` must be replaced, for example, `{AWS_User_Name}` should be replaced with your AWS username.
This example shows a Signatory vault configuration for AWS KMS. Text in `{}` must be replaced.


```
Expand All @@ -63,7 +61,6 @@ vaults:
awskms:
driver: awskms
config:
user_name: {AWS_User_Name}
access_key_id: {Access_Key_ID_In_AWS_User_Profile}
secret_access_key: {Secret_access_Key_ID_In_AWS_User_Profile}
region: {AWS_Region}
Expand Down
21 changes: 19 additions & 2 deletions docs/start.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ vaults:
config:
file: /etc/signatory/secret.json

watermark:
# Default
driver: file

# List enabled public keys hashes here
tezos:
# Default policy allows "block" and "endorsement" operations
Expand Down Expand Up @@ -111,7 +115,7 @@ tezos:
]
```

## Configuration Example - AWS KMS Vault
### Configuration Example - AWS KMS Vault
This configuration example uses AWS KMS as

```yaml
Expand All @@ -128,7 +132,6 @@ vaults:
aws:
driver: awskms
config:
user_name: signatory_testnets # IAM User or Role
access_key_id: <redacted> # Optional
secret_access_key: <redacted> # Optional
region: us-west-2
Expand All @@ -145,6 +148,20 @@ tezos:
- transaction
```

### Watermark backend

Basic syntax:

```yaml
# Optional
watermark:
driver: <driver>
# Optional
config: <config_object>
```

Currently three backends are supported: `file` (a default one), `mem` (for testing purpose only) and `aws`. See [AWS KMS][aws] for configuration syntax.

## Backends
* [AWS KMS](aws_kms.md)
* [Azure Key Vault](azure_kms.md)
Expand Down
19 changes: 18 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ toolchain go1.23.1

require (
cloud.google.com/go/kms v1.15.5
github.com/aws/aws-sdk-go-v2 v1.30.3
github.com/aws/aws-sdk-go-v2/config v1.27.27
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.14.10
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.34.4
github.com/aws/aws-sdk-go-v2/service/kms v1.35.3
github.com/aws/smithy-go v1.20.3
github.com/certusone/yubihsm-go v0.3.0
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0
github.com/ecadlabs/goblst v1.0.0
Expand Down Expand Up @@ -33,6 +39,18 @@ require (
cloud.google.com/go/compute v1.23.3 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v1.1.5 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.17.27 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.22.3 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.9.16 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 // indirect
github.com/cenkalti/backoff/v3 v3.2.2 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/ecadlabs/pretty v0.0.0-20230412124801-f948fc689a04 // indirect
Expand Down Expand Up @@ -64,7 +82,6 @@ require (
)

require (
github.com/aws/aws-sdk-go v1.48.11
github.com/beorn7/perks v1.0.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/enceve/crypto v0.0.0-20160707101852-34d48bb93815 // indirect
Expand Down
38 changes: 36 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,42 @@ cloud.google.com/go/kms v1.15.5 h1:pj1sRfut2eRbD9pFRjNnPNg/CzJPuQAzUujMIM1vVeM=
cloud.google.com/go/kms v1.15.5/go.mod h1:cU2H5jnp6G2TDpUGZyqTCoy1n16fbubHZjmVXSMtwDI=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aws/aws-sdk-go v1.48.11 h1:9YbiSbaF/jWi+qLRl+J5dEhr2mcbDYHmKg2V7RBcD5M=
github.com/aws/aws-sdk-go v1.48.11/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
github.com/aws/aws-sdk-go-v2 v1.30.3 h1:jUeBtG0Ih+ZIFH0F4UkmL9w3cSpaMv9tYYDbzILP8dY=
github.com/aws/aws-sdk-go-v2 v1.30.3/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc=
github.com/aws/aws-sdk-go-v2/config v1.27.27 h1:HdqgGt1OAP0HkEDDShEl0oSYa9ZZBSOmKpdpsDMdO90=
github.com/aws/aws-sdk-go-v2/config v1.27.27/go.mod h1:MVYamCg76dFNINkZFu4n4RjDixhVr51HLj4ErWzrVwg=
github.com/aws/aws-sdk-go-v2/credentials v1.17.27 h1:2raNba6gr2IfA0eqqiP2XiQ0UVOpGPgDSi0I9iAP+UI=
github.com/aws/aws-sdk-go-v2/credentials v1.17.27/go.mod h1:gniiwbGahQByxan6YjQUMcW4Aov6bLC3m+evgcoN4r4=
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.14.10 h1:orAIBscNu5aIjDOnKIrjO+IUFPMLKj3Lp0bPf4chiPc=
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.14.10/go.mod h1:GNjJ8daGhv10hmQYCnmkV8HuY6xXOXV4vzBssSjEIlU=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 h1:KreluoV8FZDEtI6Co2xuNk/UqI9iwMrOx/87PBNIKqw=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11/go.mod h1:SeSUYBLsMYFoRvHE0Tjvn7kbxaUhl75CJi1sbfhMxkU=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 h1:SoNJ4RlFEQEbtDcCEt+QG56MY4fm4W8rYirAmq+/DdU=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15/go.mod h1:U9ke74k1n2bf+RIgoX1SXFed1HLs51OgUSs+Ph0KJP8=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 h1:C6WHdGnTDIYETAm5iErQUiVNsclNx9qbJVPIt03B6bI=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15/go.mod h1:ZQLZqhcu+JhSrA9/NXRm8SkDvsycE+JkV3WGY41e+IM=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY=
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.34.4 h1:utG3S4T+X7nONPIpRoi1tVcQdAdJxntiVS2yolPJyXc=
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.34.4/go.mod h1:q9vzW3Xr1KEXa8n4waHiFt1PrppNDlMymlYP+xpsFbY=
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.22.3 h1:r27/FnxLPixKBRIlslsvhqscBuMK8uysCYG9Kfgm098=
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.22.3/go.mod h1:jqOFyN+QSWSoQC+ppyc4weiO8iNQXbzRbxDjQ1ayYd4=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 h1:dT3MqvGhSoaIhRseqw2I0yH81l7wiR2vjs57O51EAm8=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3/go.mod h1:GlAeCkHwugxdHaueRr4nhPuY+WW+gR8UjlcqzPr1SPI=
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.9.16 h1:lhAX5f7KpgwyieXjbDnRTjPEUI0l3emSRyxXj1PXP8w=
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.9.16/go.mod h1:AblAlCwvi7Q/SFowvckgN+8M3uFPlopSYeLlbNDArhA=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 h1:HGErhhrxZlQ044RiM+WdoZxp0p+EGM62y3L6pwA4olE=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17/go.mod h1:RkZEx4l0EHYDJpWppMJ3nD9wZJAa8/0lq9aVC+r2UII=
github.com/aws/aws-sdk-go-v2/service/kms v1.35.3 h1:UPTdlTOwWUX49fVi7cymEN6hDqCwe3LNv1vi7TXUutk=
github.com/aws/aws-sdk-go-v2/service/kms v1.35.3/go.mod h1:gjDP16zn+WWalyaUqwCCioQ8gU8lzttCCc9jYsiQI/8=
github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 h1:BXx0ZIxvrJdSgSvKTZ+yRBeSqqgPM89VPlulEcl37tM=
github.com/aws/aws-sdk-go-v2/service/sso v1.22.4/go.mod h1:ooyCOXjvJEsUw7x+ZDHeISPMhtwI3ZCB7ggFMcFfWLU=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 h1:yiwVzJW2ZxZTurVbYWA7QOrAaCYQR72t0wrSBfoesUE=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4/go.mod h1:0oxfLkpz3rQ/CHlx5hB7H69YUpFiI1tql6Q6Ne+1bCw=
github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 h1:ZsDKRLXGWHk8WdtyYMoGNO7bTudrvuKpDKgMVRlepGE=
github.com/aws/aws-sdk-go-v2/service/sts v1.30.3/go.mod h1:zwySh8fpFyXp9yOr/KVzxOl8SRqgf/IDw5aUt9UKFcQ=
github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE=
github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
Expand Down
10 changes: 10 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ type Config struct {
Server ServerConfig `yaml:"server"`
PolicyHook *PolicyHook `yaml:"policy_hook"`
BaseDir string `yaml:"base_dir" validate:"required"`
Watermark *WatermarkConfig `yaml:"watermark"`
}

// WatermarkConfig represents watermark backend configuration
type WatermarkConfig struct {
Driver string `yaml:"driver" validate:"required"`
Config yaml.Node `yaml:"config"`
}

var defaultConfig = Config{
Expand All @@ -59,6 +66,9 @@ var defaultConfig = Config{
UtilityAddress: ":9583",
},
BaseDir: "/var/lib/signatory",
Watermark: &WatermarkConfig{
Driver: "file",
},
}

// Read read the config from a file
Expand Down
5 changes: 3 additions & 2 deletions pkg/signatory/policy_hook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/ecadlabs/signatory/pkg/config"
"github.com/ecadlabs/signatory/pkg/hashmap"
"github.com/ecadlabs/signatory/pkg/signatory"
"github.com/ecadlabs/signatory/pkg/signatory/watermark"
"github.com/ecadlabs/signatory/pkg/vault"
"github.com/ecadlabs/signatory/pkg/vault/memory"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -99,7 +100,7 @@ func testPolicyHookAuth(t *testing.T, status int) error {

conf := signatory.Config{
Vaults: map[string]*config.VaultConfig{"mock": {Driver: "mock"}},
Watermark: signatory.IgnoreWatermark{},
Watermark: watermark.Ignore{},
VaultFactory: vault.FactoryFunc(func(ctx context.Context, name string, conf *yaml.Node) (vault.Vault, error) {
return memory.New([]*memory.PrivateKey{
{
Expand Down Expand Up @@ -138,7 +139,7 @@ func testPolicyHook(t *testing.T, status int) error {

conf := signatory.Config{
Vaults: map[string]*config.VaultConfig{"mock": {Driver: "mock"}},
Watermark: signatory.IgnoreWatermark{},
Watermark: watermark.Ignore{},
VaultFactory: vault.FactoryFunc(func(ctx context.Context, name string, conf *yaml.Node) (vault.Vault, error) {
return memory.New([]*memory.PrivateKey{
{
Expand Down
5 changes: 3 additions & 2 deletions pkg/signatory/signatory.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/ecadlabs/signatory/pkg/errors"
"github.com/ecadlabs/signatory/pkg/hashmap"
"github.com/ecadlabs/signatory/pkg/signatory/request"
"github.com/ecadlabs/signatory/pkg/signatory/watermark"
"github.com/ecadlabs/signatory/pkg/vault"
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v3"
Expand Down Expand Up @@ -393,7 +394,7 @@ func (s *Signatory) Sign(ctx context.Context, req *SignRequest) (crypt.Signature
l.WithField(logRaw, hex.EncodeToString(req.Message)).Log(level, "About to sign raw bytes")
digest := crypt.DigestFunc(req.Message)
signFunc := func(ctx context.Context, message []byte, key vault.StoredKey) (crypt.Signature, error) {
if err = s.config.Watermark.IsSafeToSign(req.PublicKeyHash, msg, &digest); err != nil {
if err = s.config.Watermark.IsSafeToSign(ctx, req.PublicKeyHash, msg, &digest); err != nil {
err = errors.Wrap(err, http.StatusConflict)
l.Error(err)
return nil, err
Expand Down Expand Up @@ -544,7 +545,7 @@ type Config struct {
Policy Policy
Vaults map[string]*config.VaultConfig
Interceptor SignInterceptor
Watermark Watermark
Watermark watermark.Watermark
Logger log.FieldLogger
VaultFactory vault.Factory
PolicyHook *PolicyHook
Expand Down
7 changes: 4 additions & 3 deletions pkg/signatory/signatory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/ecadlabs/signatory/pkg/config"
"github.com/ecadlabs/signatory/pkg/hashmap"
"github.com/ecadlabs/signatory/pkg/signatory"
"github.com/ecadlabs/signatory/pkg/signatory/watermark"
"github.com/ecadlabs/signatory/pkg/vault"
"github.com/ecadlabs/signatory/pkg/vault/memory"
"github.com/stretchr/testify/require"
Expand All @@ -23,7 +24,7 @@ const privateKey = "edsk4FTF78Qf1m2rykGpHqostAiq5gYW4YZEoGUSWBTJr2njsDHSnd"
func TestImport(t *testing.T) {
conf := signatory.Config{
Vaults: map[string]*config.VaultConfig{"mock": {Driver: "mock"}},
Watermark: signatory.IgnoreWatermark{},
Watermark: watermark.Ignore{},
VaultFactory: vault.FactoryFunc(func(ctx context.Context, name string, conf *yaml.Node) (vault.Vault, error) {
v, err := memory.New(nil, "Mock")
if err != nil {
Expand Down Expand Up @@ -310,7 +311,7 @@ func TestPolicy(t *testing.T) {
t.Run(c.title, func(t *testing.T) {
conf := signatory.Config{
Vaults: map[string]*config.VaultConfig{"mock": {Driver: "mock"}},
Watermark: signatory.IgnoreWatermark{},
Watermark: watermark.Ignore{},
VaultFactory: vault.FactoryFunc(func(ctx context.Context, name string, conf *yaml.Node) (vault.Vault, error) {
return memory.NewUnparsed([]*memory.UnparsedKey{{Data: privateKey}}, "Mock"), nil
}),
Expand Down Expand Up @@ -400,7 +401,7 @@ func TestListPublicKeys(t *testing.T) {
t.Run(c.title, func(t *testing.T) {
conf := signatory.Config{
Vaults: map[string]*config.VaultConfig{"test": {Driver: "test"}},
Watermark: signatory.IgnoreWatermark{},
Watermark: watermark.Ignore{},
VaultFactory: vault.FactoryFunc(func(ctx context.Context, name string, conf *yaml.Node) (vault.Vault, error) {
return NewTestVault(nil, c.lpk, nil, nil, "test"), nil
}),
Expand Down
21 changes: 0 additions & 21 deletions pkg/signatory/watermark.go

This file was deleted.

Loading
Loading