Skip to content

Commit

Permalink
New policy syntax (#241)
Browse files Browse the repository at this point in the history
* New policy syntax

* accept an old policy syntax with a warning

* Fix unit tests

Co-authored-by: Daniele Lisi <[email protected]>
  • Loading branch information
e-asphyx and danielelisi authored Sep 29, 2022
1 parent 9102a42 commit 5a37552
Show file tree
Hide file tree
Showing 12 changed files with 275 additions and 114 deletions.
50 changes: 50 additions & 0 deletions cmd/commands/list_ops.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package commands

import (
"os"
"text/template"

"github.com/ecadlabs/signatory/pkg/tezos"
"github.com/spf13/cobra"
)

const listReqTemplateSrc = `Possible request types:
{{- range .}}
- {{.}}
{{- end}}
`

const listOpsTemplateSrc = `Possible operation types:
{{- range .}}
- {{.}}
{{- end}}
`

var (
listReqTpl = template.Must(template.New("list").Parse(listReqTemplateSrc))
listOpsTpl = template.Must(template.New("list").Parse(listOpsTemplateSrc))
)

func NewListRequests(c *Context) *cobra.Command {
cmd := &cobra.Command{
Use: "list-requests",
Short: "Print possible request types",
RunE: func(cmd *cobra.Command, args []string) error {
return listReqTpl.Execute(os.Stdout, tezos.RequestKinds)
},
}

return cmd
}

func NewListOps(c *Context) *cobra.Command {
cmd := &cobra.Command{
Use: "list-ops",
Short: "Print possible operation types inside the `generic` request",
RunE: func(cmd *cobra.Command, args []string) error {
return listOpsTpl.Execute(os.Stdout, tezos.Operations)
},
}

return cmd
}
6 changes: 5 additions & 1 deletion cmd/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package commands
import (
"context"
"os"
"strings"

"github.com/ecadlabs/signatory/pkg/config"
"github.com/ecadlabs/signatory/pkg/metrics"
Expand Down Expand Up @@ -32,7 +33,10 @@ func NewRootCommand(c *Context, name string) *cobra.Command {
Use: name,
Short: "A Tezos Remote Signer for signing block-chain operations with private keys",
PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) {
if cmd.Use == "version" {
if cmd.Use == "version" ||
strings.Contains(cmd.CommandPath(), "ledger") ||
strings.Contains(cmd.CommandPath(), "list-requests") ||
strings.Contains(cmd.CommandPath(), "list-ops") {
return nil
}

Expand Down
4 changes: 2 additions & 2 deletions cmd/commands/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ Vault: {{.VaultName}}
ID: {{.ID}}
Active: {{.Active}}
{{with .Policy -}}
Allowed Operations: {{.AllowedOperations}}
Allowed Kinds: {{.AllowedKinds}}
Allowed Requests: {{.AllowedRequests}}
Allowed Operations: {{.AllowedOps}}
{{end}}
{{end -}}
`
Expand Down
2 changes: 2 additions & 0 deletions cmd/signatory-cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ func newRootCommand(ctx context.Context) *cobra.Command {
commands.NewListCommand(&rootCtx),
commands.NewImportCommand(&rootCtx),
commands.NewVersionCommand(&rootCtx),
commands.NewListRequests(&rootCtx),
commands.NewListOps(&rootCtx),
)

// Vault specific
Expand Down
4 changes: 2 additions & 2 deletions integration_test/signatory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ func TestSignatory(t *testing.T) {
}),
Policy: map[string]*signatory.Policy{
pub: {
AllowedOperations: []string{"generic", "block", "endorsement"},
AllowedKinds: []string{"endorsement", "seed_nonce_revelation", "activate_account", "ballot", "reveal", "transaction", "origination", "delegation"},
AllowedRequests: []string{"generic", "block", "endorsement"},
AllowedOps: []string{"endorsement", "seed_nonce_revelation", "activate_account", "ballot", "reveal", "transaction", "origination", "delegation"},
},
},
}
Expand Down
9 changes: 5 additions & 4 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ type TezosConfig map[string]*TezosPolicy

// TezosPolicy contains policy definition for a specific address
type TezosPolicy struct {
AllowedOperations []string `yaml:"allowed_operations" validate:"dive,oneof=generic block endorsement"`
AllowedKinds []string `yaml:"allowed_kinds" validate:"dive,oneof=endorsement seed_nonce_revelation double_endorsement_evidence double_baking_evidence activate_account ballot proposals reveal transaction origination delegation"`
LogPayloads bool `yaml:"log_payloads"`
AuthorizedKeys *AuthorizedKeys `yaml:"authorized_keys"`
Allow map[string][]string `yaml:"allow"`
AllowedOperations []string `yaml:"allowed_operations"`
AllowedKinds []string `yaml:"allowed_kinds"`
LogPayloads bool `yaml:"log_payloads"`
AuthorizedKeys *AuthorizedKeys `yaml:"authorized_keys"`
}

// VaultConfig represents single vault instance
Expand Down
62 changes: 48 additions & 14 deletions pkg/signatory/signatory.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/ecadlabs/signatory/pkg/tezos/utils"
"github.com/ecadlabs/signatory/pkg/vault"
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v3"
)

var (
Expand Down Expand Up @@ -53,8 +54,8 @@ type SignInterceptorOptions struct {

// Policy contains policy data related to the key
type Policy struct {
AllowedOperations []string
AllowedKinds []string
AllowedRequests []string
AllowedOps []string
LogPayloads bool
AuthorizedKeyHashes []string
}
Expand Down Expand Up @@ -130,7 +131,7 @@ func (s *Signatory) logger() log.FieldLogger {
}

var defaultPolicy = Policy{
AllowedOperations: []string{"block", "preendorsement", "endorsement"},
AllowedRequests: []string{"block", "preendorsement", "endorsement"},
}

func (s *Signatory) fetchPolicyOrDefault(keyHash string) *Policy {
Expand Down Expand Up @@ -165,7 +166,7 @@ func matchFilter(policy *Policy, req *SignRequest, msg tezos.UnsignedMessage) er

kind := msg.MessageKind()
var allowed bool
for _, k := range policy.AllowedOperations {
for _, k := range policy.AllowedRequests {
if kind == k {
allowed = true
break
Expand All @@ -180,7 +181,7 @@ func matchFilter(policy *Policy, req *SignRequest, msg tezos.UnsignedMessage) er
for _, op := range ops.Contents {
kind := op.OperationKind()
allowed = false
for _, k := range policy.AllowedKinds {
for _, k := range policy.AllowedOps {
if kind == k {
allowed = true
break
Expand Down Expand Up @@ -487,16 +488,49 @@ func PreparePolicy(src config.TezosConfig) (map[string]*Policy, error) {
LogPayloads: v.LogPayloads,
}

if v.AllowedKinds != nil {
pol.AllowedKinds = make([]string, len(v.AllowedKinds))
copy(pol.AllowedKinds, v.AllowedKinds)
sort.Strings(pol.AllowedKinds)
}
if v.Allow != nil {
pol.AllowedRequests = make([]string, 0, len(v.Allow))
for req := range v.Allow {
pol.AllowedRequests = append(pol.AllowedRequests, req)
}
sort.Strings(pol.AllowedRequests)

if v.AllowedOperations != nil {
pol.AllowedOperations = make([]string, len(v.AllowedOperations))
copy(pol.AllowedOperations, v.AllowedOperations)
sort.Strings(pol.AllowedOperations)
if ops, ok := v.Allow["generic"]; ok {
pol.AllowedOps = make([]string, len(ops))
copy(pol.AllowedOps, ops)
sort.Strings(pol.AllowedOps)
}
} else if v.AllowedKinds != nil || v.AllowedOperations != nil {
if v.AllowedOperations != nil {
pol.AllowedRequests = make([]string, len(v.AllowedOperations))
copy(pol.AllowedRequests, v.AllowedOperations)
sort.Strings(pol.AllowedRequests)
}
if v.AllowedKinds != nil {
pol.AllowedOps = make([]string, len(v.AllowedKinds))
copy(pol.AllowedOps, v.AllowedKinds)
sort.Strings(pol.AllowedOps)
}
log.Warnln("`allowed_operations` and `allowed_kinds` options are deprecated. Use `allow` instead:")
type example struct {
Allow map[string][]string `yaml:"allow"`
}
e := example{
Allow: make(map[string][]string),
}
for _, r := range pol.AllowedRequests {
e.Allow[r] = nil
}
if pol.AllowedOps != nil {
e.Allow["generic"] = pol.AllowedOps
}
out, err := yaml.Marshal(&e)
if err != nil {
panic(err)
}
pipe := log.StandardLogger().WriterLevel(log.WarnLevel)
pipe.Write(out)
pipe.Close()
}

if v.AuthorizedKeys != nil {
Expand Down
Loading

0 comments on commit 5a37552

Please sign in to comment.