From dc8b58d0eb7ebf7649bb613cdd76fed2c7f87d10 Mon Sep 17 00:00:00 2001 From: oppiliappan Date: Tue, 29 Jul 2025 12:17:05 +0000 Subject: [PATCH] spindle: introduce secret manager interface Signed-off-by: oppiliappan --- spindle/secrets/manager.go | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file(s) changed, 63 insertion(s)(+), 0 deletion(s)(-) diff --git a/spindle/secrets/manager.go b/spindle/secrets/manager.go new file mode 100644 --- /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 +} -- tangled.sh