From b6c8564d676fd47b6e58e41d7bb08cecab263db7 Mon Sep 17 00:00:00 2001 From: oppiliappan Date: Tue, 29 Jul 2025 13:17:05 +0100 Subject: [PATCH] spindle: introduce secret manager interface Change-Id: wqllrttkrwktwztvxpwunwqxmukwvtkr Signed-off-by: oppiliappan --- spindle/secrets/manager.go | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 spindle/secrets/manager.go diff --git a/spindle/secrets/manager.go b/spindle/secrets/manager.go new file mode 100644 index 0000000..1e9eeab --- /dev/null +++ b/spindle/secrets/manager.go @@ -0,0 +1,63 @@ +package secrets + +import ( + "errors" + "regexp" + "time" + + "github.com/bluesky-social/indigo/atproto/syntax" +) + +type DidSlashRepo string + +type Secret[T any] struct { + Key string + Value T + Repo DidSlashRepo + CreatedAt time.Time + CreatedBy syntax.DID +} + +// the secret is not present +type LockedSecret = Secret[struct{}] + +// the secret is present in plaintext, never expose this publicly, +// only use in the workflow engine +type UnlockedSecret = Secret[string] + +type Manager interface { + AddSecret(secret UnlockedSecret) error + RemoveSecret(secret Secret[any]) error + GetSecretsLocked(repo DidSlashRepo) ([]LockedSecret, error) + GetSecretsUnlocked(repo DidSlashRepo) ([]UnlockedSecret, error) +} + +var ErrKeyAlreadyPresent = errors.New("key already present") +var ErrInvalidKeyIdent = errors.New("key is not a valid identifier") +var ErrKeyNotFound = errors.New("key not found") + +// ensure that we are satisfying the interface +var ( + _ = []Manager{ + &SqliteManager{}, + } +) + +var ( + // bash identifier syntax + keyIdent = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_]*$`) +) + +func isValidKey(key string) bool { + if key == "" { + return false + } + return keyIdent.MatchString(key) +} + +func ValidateKey(key string) error { + if !isValidKey(key) { + return ErrInvalidKeyIdent + } + return nil +} -- 2.43.0