feat: share.keyRules, how long and varied a share key must be
Sharing refuses a key shorter than minLength characters (default 32, never under 16) or of fewer than minClasses kinds of lowercase, uppercase, digits and symbols (default 2, so random hex passes), saying so without showing it. Opening doesn't check. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
13 files changed
+156
-21
No files matched your search
@@ -317,7 +317,7 @@ Flags:
|
||||
if shareArgs != nil {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), *timeout)
|
||||
defer cancel()
|
||||
return shareFiles(ctx, providers, st, cfg.Share.Key, shareArgs, os.Stdout)
|
||||
return shareFiles(ctx, providers, st, cfg.Share.Key, shareRules(cfg), shareArgs, os.Stdout)
|
||||
}
|
||||
|
||||
// Links opened elsewhere (lazysecrets launch) can come here.
|
||||
@@ -391,6 +391,7 @@ Flags:
|
||||
Changelog: lazysecrets.Changelog,
|
||||
Dir: placeDir,
|
||||
ShareKey: cfg.Share.Key,
|
||||
ShareRules: shareRules(cfg),
|
||||
Open: open,
|
||||
Styles: &theme,
|
||||
DefaultFg: defaultFg,
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"git.kebcloud.no/keb/lazysecrets/internal/config"
|
||||
"git.kebcloud.no/keb/lazysecrets/internal/provider"
|
||||
"git.kebcloud.no/keb/lazysecrets/internal/provider/repo"
|
||||
"git.kebcloud.no/keb/lazysecrets/internal/share"
|
||||
@@ -19,7 +20,7 @@ import (
|
||||
// the --key secret's value, else the repo's or the config's share.key:
|
||||
//
|
||||
// lazysecrets share .env apps/api/.env
|
||||
func shareFiles(ctx context.Context, providers []provider.Provider, st *store.Store, general string, args []string, out io.Writer) error {
|
||||
func shareFiles(ctx context.Context, providers []provider.Provider, st *store.Store, general string, rules share.Rules, args []string, out io.Writer) error {
|
||||
fs := flag.NewFlagSet("share", flag.ContinueOnError)
|
||||
keyLink := fs.String("key", "", "the secret to encrypt with: its lazysecrets:// link, Key Vault URL or reference (default: share.key)")
|
||||
if err := fs.Parse(args); err != nil {
|
||||
@@ -78,10 +79,15 @@ func shareFiles(ctx context.Context, providers []provider.Provider, st *store.St
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading the key %s: %w", key, err)
|
||||
}
|
||||
link, err := share.Seal(share.Header{Key: share.Pin(key, version), Repo: id}, []byte(v.Reveal()), files)
|
||||
link, err := share.Seal(share.Header{Key: share.Pin(key, version), Repo: id}, []byte(v.Reveal()), files, rules)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = fmt.Fprintln(out, link)
|
||||
return err
|
||||
}
|
||||
|
||||
// shareRules are the config's share.keyRules.
|
||||
func shareRules(cfg config.Config) share.Rules {
|
||||
return share.Rules{MinLength: cfg.Share.KeyRules.MinLength, MinClasses: cfg.Share.KeyRules.MinClasses}
|
||||
}
|
||||
@@ -16,6 +16,9 @@ import (
|
||||
"git.kebcloud.no/keb/lazysecrets/internal/store"
|
||||
)
|
||||
|
||||
// demoRules take the demo key, made up to be remembered.
|
||||
var demoRules = share.Rules{MinLength: 16, MinClasses: 1}
|
||||
|
||||
func TestShareFiles(t *testing.T) {
|
||||
root, _ := filepath.EvalSymlinks(t.TempDir())
|
||||
for _, args := range [][]string{{"init", "-q"}, {"remote", "add", "origin", "git@git.example.com:team/app.git"}} {
|
||||
@@ -31,7 +34,7 @@ func TestShareFiles(t *testing.T) {
|
||||
key := "lazysecrets://azure/kv-app-prod.vault.azure.net/secrets/db-password"
|
||||
|
||||
var out bytes.Buffer
|
||||
if err := shareFiles(ctx, providers, st, key, []string{filepath.Join(root, ".env")}, &out); err != nil {
|
||||
if err := shareFiles(ctx, providers, st, key, demoRules, []string{filepath.Join(root, ".env")}, &out); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r, err := ref.Parse(strings.TrimSpace(out.String()))
|
||||
@@ -57,7 +60,7 @@ func TestShareFiles(t *testing.T) {
|
||||
{key, nil, "usage"},
|
||||
{"", []string{"--key", "lazysecrets://azure/kv-app-prod.vault.azure.net", filepath.Join(root, ".env")}, "isn't a secret"},
|
||||
} {
|
||||
if err := shareFiles(ctx, providers, st, c.general, c.args, &out); err == nil || !strings.Contains(err.Error(), c.want) {
|
||||
if err := shareFiles(ctx, providers, st, c.general, demoRules, c.args, &out); err == nil || !strings.Contains(err.Error(), c.want) {
|
||||
t.Errorf("%v: %v, want %q", c.args, err, c.want)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user