diff --git a/spindle/engine/engine.go b/spindle/engine/engine.go --- a/spindle/engine/engine.go +++ b/spindle/engine/engine.go @@ -27,7 +27,7 @@ // extract secrets var allSecrets []secrets.UnlockedSecret if didSlashRepo, err := securejoin.SecureJoin(pipeline.RepoOwner, pipeline.RepoName); err == nil { - if res, err := vault.GetSecretsUnlocked(ctx, secrets.DidSlashRepo(didSlashRepo)); err == nil { + if res, err := vault.GetSecretsUnlocked(ctx, secrets.RepoIdentifier(didSlashRepo)); err == nil { allSecrets = res } } diff --git a/spindle/ingester.go b/spindle/ingester.go --- a/spindle/ingester.go +++ b/spindle/ingester.go @@ -228,40 +228,46 @@ if err != nil || subjectId.Handle.IsInvalidHandle() { return err } - repoAt, err := syntax.ParseATURI(record.Repo) - if err != nil { - l.Info("rejecting record, invalid repoAt", "repoAt", record.Repo) - return nil - } + var rbacResource string + var ownerDid string + switch { + case record.Repo != nil: + repoAt, parseErr := syntax.ParseATURI(*record.Repo) + if parseErr != nil { + l.Info("rejecting record, invalid repoAt", "repoAt", *record.Repo) + return nil + } - // TODO: get rid of this entirely - // resolve this aturi to extract the repo record - owner, err := s.res.ResolveIdent(ctx, repoAt.Authority().String()) - if err != nil || owner.Handle.IsInvalidHandle() { - return fmt.Errorf("failed to resolve handle: %w", err) - } + owner, resolveErr := s.res.ResolveIdent(ctx, repoAt.Authority().String()) + if resolveErr != nil || owner.Handle.IsInvalidHandle() { + return fmt.Errorf("failed to resolve handle: %w", resolveErr) + } - xrpcc := xrpc.Client{ - Host: owner.PDSEndpoint(), - } + xrpcc := xrpc.Client{ + Host: owner.PDSEndpoint(), + } - resp, err := comatproto.RepoGetRecord(ctx, &xrpcc, "", tangled.RepoNSID, repoAt.Authority().String(), repoAt.RecordKey().String()) - if err != nil { - return err + resp, getErr := comatproto.RepoGetRecord(ctx, &xrpcc, "", tangled.RepoNSID, repoAt.Authority().String(), repoAt.RecordKey().String()) + if getErr != nil { + return getErr + } + + repo := resp.Value.Val.(*tangled.Repo) + rbacResource, _ = securejoin.SecureJoin(owner.DID.String(), repo.Name) + ownerDid = owner.DID.String() + + default: + l.Info("rejecting collaborator record without repo at-uri (spindle RBAC keyed by owner/name)") + return nil } - repo := resp.Value.Val.(*tangled.Repo) - didSlashRepo, _ := securejoin.SecureJoin(owner.DID.String(), repo.Name) - - // check perms for this user - if ok, err := s.e.IsCollaboratorInviteAllowed(owner.DID.String(), rbac.ThisServer, didSlashRepo); !ok || err != nil { + if ok, err := s.e.IsCollaboratorInviteAllowed(ownerDid, rbac.ThisServer, rbacResource); !ok || err != nil { return fmt.Errorf("insufficient permissions: %w", err) } - // add collaborator to rbac - if err := s.e.AddCollaborator(record.Subject, rbac.ThisServer, didSlashRepo); err != nil { - l.Error("failed to add repo to enforcer", "error", err) - return fmt.Errorf("failed to add repo: %w", err) + if err := s.e.AddCollaborator(record.Subject, rbac.ThisServer, rbacResource); err != nil { + l.Error("failed to add collaborator to enforcer", "error", err) + return fmt.Errorf("failed to add collaborator: %w", err) } return nil diff --git a/spindle/models/clone.go b/spindle/models/clone.go --- a/spindle/models/clone.go +++ b/spindle/models/clone.go @@ -120,8 +120,14 @@ if devMode && strings.Contains(host, "localhost") { host = strings.ReplaceAll(host, "localhost", "host.docker.internal") } - // Build URL: {scheme}{knot}/{did}/{repo} - return fmt.Sprintf("%s%s/%s/%s", scheme, host, repo.Did, repo.Repo) + switch { + case repo.RepoDid != nil: + return fmt.Sprintf("%s%s/%s", scheme, host, *repo.RepoDid) + case repo.Repo != nil: + return fmt.Sprintf("%s%s/%s/%s", scheme, host, repo.Did, *repo.Repo) + default: + return "" + } } // buildFetchArgs constructs the arguments for git fetch based on clone options diff --git a/spindle/models/pipeline_env.go b/spindle/models/pipeline_env.go --- a/spindle/models/pipeline_env.go +++ b/spindle/models/pipeline_env.go @@ -26,7 +26,12 @@ // Repo info if tr.Repo != nil { env["TANGLED_REPO_KNOT"] = tr.Repo.Knot env["TANGLED_REPO_DID"] = tr.Repo.Did - env["TANGLED_REPO_NAME"] = tr.Repo.Repo + if tr.Repo.Repo != nil { + env["TANGLED_REPO_NAME"] = *tr.Repo.Repo + } + if tr.Repo.RepoDid != nil { + env["TANGLED_REPO_REPO_DID"] = *tr.Repo.RepoDid + } env["TANGLED_REPO_DEFAULT_BRANCH"] = tr.Repo.DefaultBranch env["TANGLED_REPO_URL"] = BuildRepoURL(tr.Repo, devMode) } diff --git a/spindle/secrets/manager.go b/spindle/secrets/manager.go --- a/spindle/secrets/manager.go +++ b/spindle/secrets/manager.go @@ -9,12 +9,12 @@ "github.com/bluesky-social/indigo/atproto/syntax" ) -type DidSlashRepo string +type RepoIdentifier string type Secret[T any] struct { Key string Value T - Repo DidSlashRepo + Repo RepoIdentifier CreatedAt time.Time CreatedBy syntax.DID } @@ -29,8 +29,8 @@ type Manager interface { AddSecret(ctx context.Context, secret UnlockedSecret) error RemoveSecret(ctx context.Context, secret Secret[any]) error - GetSecretsLocked(ctx context.Context, repo DidSlashRepo) ([]LockedSecret, error) - GetSecretsUnlocked(ctx context.Context, repo DidSlashRepo) ([]UnlockedSecret, error) + GetSecretsLocked(ctx context.Context, repo RepoIdentifier) ([]LockedSecret, error) + GetSecretsUnlocked(ctx context.Context, repo RepoIdentifier) ([]UnlockedSecret, error) } // stopper interface for managers that need cleanup diff --git a/spindle/secrets/openbao.go b/spindle/secrets/openbao.go --- a/spindle/secrets/openbao.go +++ b/spindle/secrets/openbao.go @@ -149,7 +149,7 @@ v.logger.Debug("secret removed successfully", "repo", secret.Repo, "key", secret.Key) return nil } -func (v *OpenBaoManager) GetSecretsLocked(ctx context.Context, repo DidSlashRepo) ([]LockedSecret, error) { +func (v *OpenBaoManager) GetSecretsLocked(ctx context.Context, repo RepoIdentifier) ([]LockedSecret, error) { repoPath := v.buildRepoPath(repo) secretsList, err := v.client.Logical().ListWithContext(ctx, fmt.Sprintf("%s/metadata/%s", v.mountPath, repoPath)) @@ -224,7 +224,7 @@ v.logger.Debug("retrieved locked secrets", "repo", repo, "count", len(secrets)) return secrets, nil } -func (v *OpenBaoManager) GetSecretsUnlocked(ctx context.Context, repo DidSlashRepo) ([]UnlockedSecret, error) { +func (v *OpenBaoManager) GetSecretsUnlocked(ctx context.Context, repo RepoIdentifier) ([]UnlockedSecret, error) { repoPath := v.buildRepoPath(repo) secretsList, err := v.client.Logical().ListWithContext(ctx, fmt.Sprintf("%s/metadata/%s", v.mountPath, repoPath)) @@ -307,8 +307,8 @@ return secrets, nil } // buildRepoPath creates a safe path for a repository -func (v *OpenBaoManager) buildRepoPath(repo DidSlashRepo) string { - // convert DidSlashRepo to a safe path by replacing special characters +func (v *OpenBaoManager) buildRepoPath(repo RepoIdentifier) string { + // convert RepoIdentifier to a safe path by replacing special characters repoPath := strings.ReplaceAll(string(repo), "/", "_") repoPath = strings.ReplaceAll(repoPath, ":", "_") repoPath = strings.ReplaceAll(repoPath, ".", "_") @@ -316,6 +316,6 @@ return fmt.Sprintf("repos/%s", repoPath) } // buildSecretPath creates a path for a specific secret -func (v *OpenBaoManager) buildSecretPath(repo DidSlashRepo, key string) string { +func (v *OpenBaoManager) buildSecretPath(repo RepoIdentifier, key string) string { return path.Join(v.buildRepoPath(repo), key) } diff --git a/spindle/secrets/openbao_test.go b/spindle/secrets/openbao_test.go --- a/spindle/secrets/openbao_test.go +++ b/spindle/secrets/openbao_test.go @@ -32,7 +32,7 @@ m.shouldError = false m.errorToReturn = nil } -func (m *MockOpenBaoManager) buildKey(repo DidSlashRepo, key string) string { +func (m *MockOpenBaoManager) buildKey(repo RepoIdentifier, key string) string { return string(repo) + "_" + key } @@ -64,7 +64,7 @@ delete(m.secrets, key) return nil } -func (m *MockOpenBaoManager) GetSecretsLocked(ctx context.Context, repo DidSlashRepo) ([]LockedSecret, error) { +func (m *MockOpenBaoManager) GetSecretsLocked(ctx context.Context, repo RepoIdentifier) ([]LockedSecret, error) { if m.shouldError { return nil, m.errorToReturn } @@ -84,7 +84,7 @@ return result, nil } -func (m *MockOpenBaoManager) GetSecretsUnlocked(ctx context.Context, repo DidSlashRepo) ([]UnlockedSecret, error) { +func (m *MockOpenBaoManager) GetSecretsUnlocked(ctx context.Context, repo RepoIdentifier) ([]UnlockedSecret, error) { if m.shouldError { return nil, m.errorToReturn } @@ -103,7 +103,7 @@ func createTestSecretForOpenBao(repo, key, value, createdBy string) UnlockedSecret { return UnlockedSecret{ Key: key, Value: value, - Repo: DidSlashRepo(repo), + Repo: RepoIdentifier(repo), CreatedAt: time.Now(), CreatedBy: syntax.DID(createdBy), } @@ -173,19 +173,19 @@ manager := &OpenBaoManager{mountPath: "secret"} tests := []struct { name string - repo DidSlashRepo + repo RepoIdentifier key string expected string }{ { name: "simple repo path", - repo: DidSlashRepo("did:plc:foo/repo"), + repo: RepoIdentifier("did:plc:foo/repo"), key: "api_key", expected: "repos/did_plc_foo_repo/api_key", }, { name: "complex repo path with dots", - repo: DidSlashRepo("did:web:example.com/my-repo"), + repo: RepoIdentifier("did:web:example.com/my-repo"), key: "secret_key", expected: "repos/did_web_example_com_my-repo/secret_key", }, @@ -204,7 +204,7 @@ manager := &OpenBaoManager{mountPath: "test"} tests := []struct { name string - repo DidSlashRepo + repo RepoIdentifier expected string }{ { @@ -310,7 +310,7 @@ createTestSecretForOpenBao("did:plc:test/repo1", "API_KEY", "secret123", "did:plc:creator"), }, removeSecret: Secret[any]{ Key: "API_KEY", - Repo: DidSlashRepo("did:plc:test/repo1"), + Repo: RepoIdentifier("did:plc:test/repo1"), }, expectError: false, }, @@ -319,7 +319,7 @@ name: "remove non-existent secret", setupSecrets: []UnlockedSecret{}, removeSecret: Secret[any]{ Key: "API_KEY", - Repo: DidSlashRepo("did:plc:test/repo1"), + Repo: RepoIdentifier("did:plc:test/repo1"), }, expectError: true, }, @@ -352,7 +352,7 @@ func TestMockOpenBaoManager_GetSecretsLocked(t *testing.T) { tests := []struct { name string setupSecrets []UnlockedSecret - queryRepo DidSlashRepo + queryRepo RepoIdentifier expectedCount int expectedKeys []string expectError bool @@ -364,7 +364,7 @@ createTestSecretForOpenBao("did:plc:test/repo1", "API_KEY", "secret123", "did:plc:creator"), createTestSecretForOpenBao("did:plc:test/repo1", "DB_PASSWORD", "dbpass456", "did:plc:creator"), createTestSecretForOpenBao("did:plc:test/repo2", "OTHER_KEY", "other789", "did:plc:creator"), }, - queryRepo: DidSlashRepo("did:plc:test/repo1"), + queryRepo: RepoIdentifier("did:plc:test/repo1"), expectedCount: 2, expectedKeys: []string{"API_KEY", "DB_PASSWORD"}, expectError: false, @@ -372,7 +372,7 @@ }, { name: "get secrets from empty repo", setupSecrets: []UnlockedSecret{}, - queryRepo: DidSlashRepo("did:plc:test/empty"), + queryRepo: RepoIdentifier("did:plc:test/empty"), expectedCount: 0, expectedKeys: []string{}, expectError: false, @@ -417,7 +417,7 @@ func TestMockOpenBaoManager_GetSecretsUnlocked(t *testing.T) { tests := []struct { name string setupSecrets []UnlockedSecret - queryRepo DidSlashRepo + queryRepo RepoIdentifier expectedCount int expectedSecrets map[string]string // key -> value expectError bool @@ -429,7 +429,7 @@ createTestSecretForOpenBao("did:plc:test/repo1", "API_KEY", "secret123", "did:plc:creator"), createTestSecretForOpenBao("did:plc:test/repo1", "DB_PASSWORD", "dbpass456", "did:plc:creator"), createTestSecretForOpenBao("did:plc:test/repo2", "OTHER_KEY", "other789", "did:plc:creator"), }, - queryRepo: DidSlashRepo("did:plc:test/repo1"), + queryRepo: RepoIdentifier("did:plc:test/repo1"), expectedCount: 2, expectedSecrets: map[string]string{ "API_KEY": "secret123", @@ -440,7 +440,7 @@ }, { name: "get secrets from empty repo", setupSecrets: []UnlockedSecret{}, - queryRepo: DidSlashRepo("did:plc:test/empty"), + queryRepo: RepoIdentifier("did:plc:test/empty"), expectedCount: 0, expectedSecrets: map[string]string{}, expectError: false, @@ -521,7 +521,7 @@ { name: "complete workflow", scenario: func(t *testing.T, mock *MockOpenBaoManager) { ctx := context.Background() - repo := DidSlashRepo("did:plc:test/integration") + repo := RepoIdentifier("did:plc:test/integration") // Start with empty repo secrets, err := mock.GetSecretsLocked(ctx, repo) diff --git a/spindle/secrets/sqlite.go b/spindle/secrets/sqlite.go --- a/spindle/secrets/sqlite.go +++ b/spindle/secrets/sqlite.go @@ -107,7 +107,7 @@ return nil } -func (s *SqliteManager) GetSecretsLocked(ctx context.Context, didSlashRepo DidSlashRepo) ([]LockedSecret, error) { +func (s *SqliteManager) GetSecretsLocked(ctx context.Context, didSlashRepo RepoIdentifier) ([]LockedSecret, error) { query := fmt.Sprintf(` select repo, key, created_at, created_by from %s where repo = ?; `, s.tableName) @@ -139,7 +139,7 @@ return ls, nil } -func (s *SqliteManager) GetSecretsUnlocked(ctx context.Context, didSlashRepo DidSlashRepo) ([]UnlockedSecret, error) { +func (s *SqliteManager) GetSecretsUnlocked(ctx context.Context, didSlashRepo RepoIdentifier) ([]UnlockedSecret, error) { query := fmt.Sprintf(` select repo, key, value, created_at, created_by from %s where repo = ?; `, s.tableName) diff --git a/spindle/secrets/sqlite_test.go b/spindle/secrets/sqlite_test.go --- a/spindle/secrets/sqlite_test.go +++ b/spindle/secrets/sqlite_test.go @@ -22,7 +22,7 @@ func createTestSecret(repo, key, value, createdBy string) UnlockedSecret { return UnlockedSecret{ Key: key, Value: value, - Repo: DidSlashRepo(repo), + Repo: RepoIdentifier(repo), CreatedAt: time.Now(), CreatedBy: syntax.DID(createdBy), } @@ -147,7 +147,7 @@ createTestSecret("did:plc:foo/repo", "api_key", "secret_value_123", "did:plc:example123"), }, removeSecret: Secret[any]{ Key: "api_key", - Repo: DidSlashRepo("did:plc:foo/repo"), + Repo: RepoIdentifier("did:plc:foo/repo"), }, expectError: nil, }, @@ -158,7 +158,7 @@ createTestSecret("did:plc:foo/repo", "api_key", "secret_value_123", "did:plc:example123"), }, removeSecret: Secret[any]{ Key: "non_existent_key", - Repo: DidSlashRepo("did:plc:foo/repo"), + Repo: RepoIdentifier("did:plc:foo/repo"), }, expectError: ErrKeyNotFound, }, @@ -167,7 +167,7 @@ name: "remove from empty database", setupSecrets: []UnlockedSecret{}, removeSecret: Secret[any]{ Key: "any_key", - Repo: DidSlashRepo("did:plc:foo/repo"), + Repo: RepoIdentifier("did:plc:foo/repo"), }, expectError: ErrKeyNotFound, }, @@ -178,7 +178,7 @@ createTestSecret("did:plc:foo/repo", "api_key", "secret_value_123", "did:plc:example123"), }, removeSecret: Secret[any]{ Key: "api_key", - Repo: DidSlashRepo("other.com/repo"), + Repo: RepoIdentifier("other.com/repo"), }, expectError: ErrKeyNotFound, }, @@ -209,7 +209,7 @@ func TestSqliteManager_GetSecretsLocked(t *testing.T) { tests := []struct { name string setupSecrets []UnlockedSecret - queryRepo DidSlashRepo + queryRepo RepoIdentifier expectedCount int expectedKeys []string expectError bool @@ -221,7 +221,7 @@ createTestSecret("did:plc:foo/repo", "key1", "value1", "did:plc:user1"), createTestSecret("did:plc:foo/repo", "key2", "value2", "did:plc:user2"), createTestSecret("other.com/repo", "key3", "value3", "did:plc:user3"), }, - queryRepo: DidSlashRepo("did:plc:foo/repo"), + queryRepo: RepoIdentifier("did:plc:foo/repo"), expectedCount: 2, expectedKeys: []string{"key1", "key2"}, expectError: false, @@ -232,7 +232,7 @@ setupSecrets: []UnlockedSecret{ createTestSecret("did:plc:foo/repo", "single_key", "single_value", "did:plc:user1"), createTestSecret("other.com/repo", "other_key", "other_value", "did:plc:user2"), }, - queryRepo: DidSlashRepo("did:plc:foo/repo"), + queryRepo: RepoIdentifier("did:plc:foo/repo"), expectedCount: 1, expectedKeys: []string{"single_key"}, expectError: false, @@ -242,7 +242,7 @@ name: "get secrets for non-existent repo", setupSecrets: []UnlockedSecret{ createTestSecret("did:plc:foo/repo", "key1", "value1", "did:plc:user1"), }, - queryRepo: DidSlashRepo("nonexistent.com/repo"), + queryRepo: RepoIdentifier("nonexistent.com/repo"), expectedCount: 0, expectedKeys: []string{}, expectError: false, @@ -250,7 +250,7 @@ }, { name: "get secrets from empty database", setupSecrets: []UnlockedSecret{}, - queryRepo: DidSlashRepo("did:plc:foo/repo"), + queryRepo: RepoIdentifier("did:plc:foo/repo"), expectedCount: 0, expectedKeys: []string{}, expectError: false, @@ -311,7 +311,7 @@ func TestSqliteManager_GetSecretsUnlocked(t *testing.T) { tests := []struct { name string setupSecrets []UnlockedSecret - queryRepo DidSlashRepo + queryRepo RepoIdentifier expectedCount int expectedSecrets map[string]string // key -> value expectError bool @@ -323,7 +323,7 @@ createTestSecret("did:plc:foo/repo", "key1", "value1", "did:plc:user1"), createTestSecret("did:plc:foo/repo", "key2", "value2", "did:plc:user2"), createTestSecret("other.com/repo", "key3", "value3", "did:plc:user3"), }, - queryRepo: DidSlashRepo("did:plc:foo/repo"), + queryRepo: RepoIdentifier("did:plc:foo/repo"), expectedCount: 2, expectedSecrets: map[string]string{ "key1": "value1", @@ -337,7 +337,7 @@ setupSecrets: []UnlockedSecret{ createTestSecret("did:plc:foo/repo", "single_key", "single_value", "did:plc:user1"), createTestSecret("other.com/repo", "other_key", "other_value", "did:plc:user2"), }, - queryRepo: DidSlashRepo("did:plc:foo/repo"), + queryRepo: RepoIdentifier("did:plc:foo/repo"), expectedCount: 1, expectedSecrets: map[string]string{ "single_key": "single_value", @@ -349,7 +349,7 @@ name: "get unlocked secrets for non-existent repo", setupSecrets: []UnlockedSecret{ createTestSecret("did:plc:foo/repo", "key1", "value1", "did:plc:user1"), }, - queryRepo: DidSlashRepo("nonexistent.com/repo"), + queryRepo: RepoIdentifier("nonexistent.com/repo"), expectedCount: 0, expectedSecrets: map[string]string{}, expectError: false, @@ -357,7 +357,7 @@ }, { name: "get unlocked secrets from empty database", setupSecrets: []UnlockedSecret{}, - queryRepo: DidSlashRepo("did:plc:foo/repo"), + queryRepo: RepoIdentifier("did:plc:foo/repo"), expectedCount: 0, expectedSecrets: map[string]string{}, expectError: false, @@ -429,17 +429,17 @@ secret := createTestSecret("interface.test/repo", "test_key", "test_value", "did:plc:user") return m.AddSecret(context.Background(), secret) }, func(m Manager) error { - _, err := m.GetSecretsLocked(context.Background(), DidSlashRepo("interface.test/repo")) + _, err := m.GetSecretsLocked(context.Background(), RepoIdentifier("interface.test/repo")) return err }, func(m Manager) error { - _, err := m.GetSecretsUnlocked(context.Background(), DidSlashRepo("interface.test/repo")) + _, err := m.GetSecretsUnlocked(context.Background(), RepoIdentifier("interface.test/repo")) return err }, func(m Manager) error { secret := Secret[any]{ Key: "test_key", - Repo: DidSlashRepo("interface.test/repo"), + Repo: RepoIdentifier("interface.test/repo"), } return m.RemoveSecret(context.Background(), secret) }, @@ -498,8 +498,8 @@ }{ { name: "multi-repo secret management", scenario: func(t *testing.T, manager *SqliteManager) { - repo1 := DidSlashRepo("example1.com/repo") - repo2 := DidSlashRepo("example2.com/repo") + repo1 := RepoIdentifier("example1.com/repo") + repo2 := RepoIdentifier("example2.com/repo") secrets := []UnlockedSecret{ createTestSecret(string(repo1), "db_password", "super_secret_123", "did:plc:admin"), @@ -543,7 +543,7 @@ }, { name: "empty database operations", scenario: func(t *testing.T, manager *SqliteManager) { - repo := DidSlashRepo("empty.test/repo") + repo := RepoIdentifier("empty.test/repo") // Operations on empty database should not error locked, err := manager.GetSecretsLocked(context.Background(), repo) diff --git a/spindle/server.go b/spindle/server.go --- a/spindle/server.go +++ b/spindle/server.go @@ -315,10 +315,15 @@ return fmt.Errorf("repo knot does not match event source: %s != %s", src.Key(), tpl.TriggerMetadata.Repo.Knot) } // filter by repos + repoName := "" + if tpl.TriggerMetadata.Repo.Repo != nil { + repoName = *tpl.TriggerMetadata.Repo.Repo + } + _, err = s.db.GetRepo( tpl.TriggerMetadata.Repo.Knot, tpl.TriggerMetadata.Repo.Did, - tpl.TriggerMetadata.Repo.Repo, + repoName, ) if err != nil { return fmt.Errorf("failed to get repo: %w", err) @@ -382,7 +387,7 @@ ok := s.jq.Enqueue(queue.Job{ Run: func() error { engine.StartWorkflows(log.SubLogger(s.l, "engine"), s.vault, s.cfg, s.db, s.n, ctx, &models.Pipeline{ RepoOwner: tpl.TriggerMetadata.Repo.Did, - RepoName: tpl.TriggerMetadata.Repo.Repo, + RepoName: repoName, Workflows: workflows, }, pipelineId) return nil diff --git a/spindle/xrpc/add_secret.go b/spindle/xrpc/add_secret.go --- a/spindle/xrpc/add_secret.go +++ b/spindle/xrpc/add_secret.go @@ -75,7 +75,7 @@ return } secret := secrets.UnlockedSecret{ - Repo: secrets.DidSlashRepo(didPath), + Repo: secrets.RepoIdentifier(didPath), Key: data.Key, Value: data.Value, CreatedAt: time.Now(), diff --git a/spindle/xrpc/list_secrets.go b/spindle/xrpc/list_secrets.go --- a/spindle/xrpc/list_secrets.go +++ b/spindle/xrpc/list_secrets.go @@ -69,7 +69,7 @@ writeError(w, xrpcerr.AccessControlError(actorDid.String()), http.StatusUnauthorized) return } - ls, err := x.Vault.GetSecretsLocked(r.Context(), secrets.DidSlashRepo(didPath)) + ls, err := x.Vault.GetSecretsLocked(r.Context(), secrets.RepoIdentifier(didPath)) if err != nil { l.Error("failed to get secret from vault", "did", actorDid.String(), "err", err) writeError(w, xrpcerr.GenericError(err), http.StatusInternalServerError) diff --git a/spindle/xrpc/remove_secret.go b/spindle/xrpc/remove_secret.go --- a/spindle/xrpc/remove_secret.go +++ b/spindle/xrpc/remove_secret.go @@ -69,7 +69,7 @@ return } secret := secrets.Secret[any]{ - Repo: secrets.DidSlashRepo(didPath), + Repo: secrets.RepoIdentifier(didPath), Key: data.Key, } err = x.Vault.RemoveSecret(r.Context(), secret)