Skip to content

Dev#166

Merged
vsilent merged 9 commits intomainfrom
dev
Apr 10, 2026
Merged

Dev#166
vsilent merged 9 commits intomainfrom
dev

Conversation

@vsilent
Copy link
Copy Markdown
Collaborator

@vsilent vsilent commented Apr 10, 2026

Included claude code/reviewer/tester subagents for better security tests. More IDOR security tests

vsilent and others added 9 commits April 8, 2026 15:26
- Replace #[derive(Debug)] with custom Debug impls on 11 structs that
  contain sensitive fields: Settings, DatabaseSettings, AmqpSettings,
  VaultSettings, User, Cloud, ServerForm, RegistryForm, CloudForm,
  VaultClient, AgentLoginRequest. All secret fields now print [REDACTED].

- Add skip_all to 130+ #[tracing::instrument] attributes across all
  route handlers, form helpers, and vault methods to prevent function
  parameters from being captured in tracing spans.

  impl that was printing full plaintext cloud tokens to stderr.

- Replace explicit tracing::debug! calls that formatted User/Cloud
  structs via {:?} with targeted field logging (user.id, cloud.id).

66 files changed across src/routes/, src/forms/, src/models/,
src/configuration.rs, src/helpers/vault.rs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The db::cloud::insert function used a static placeholder name '{provider}-0'
for auto-generated names, but only updated the name in memory (never in DB).
This caused duplicate key violations on the (user_id, name) unique constraint
when saving cloud credentials from env vars on subsequent deploys.

Fixes:
- Server: Use UUID suffix for placeholder names to avoid collisions, then
  UPDATE the row to the final '{provider}-{id}' name after insert
- CLI: Check if credentials already exist for the provider before inserting;
  update existing credentials via PUT instead of creating duplicates
- Add update_cloud() method to stacker_client for credential updates

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Previously, all deploy targets (local/cloud/server) shared a single
deployment.lock file. Deploying locally would overwrite the cloud
deployment record, losing remote server connection details.

Now each target gets its own lockfile:
  .stacker/deployment-local.lock
  .stacker/deployment-cloud.lock
  .stacker/deployment-server.lock

The generic load() falls back to legacy deployment.lock for backward
compatibility, and load_for_target() provides precise per-target access.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Security tests (11 new test files, 51 integration tests):
- security_project.rs: 5 tests for /project endpoint isolation
- security_cloud.rs: 5 tests for /cloud endpoint isolation
- security_server.rs: 5 tests for /server endpoint isolation
- security_deployment.rs: 5 tests for /api/v1/deployments isolation
- security_commands.rs: 3 tests for /api/v1/commands isolation
- security_pipes.rs: 5 tests for /api/v1/pipes isolation
- security_agent.rs: 7 tests for /api/v1/agent isolation
- security_client.rs: 5 tests for /client isolation
- security_chat.rs: 5 tests for /chat isolation
- security_rating.rs: 3 tests for /rating isolation
- security_admin.rs: 3 tests for admin RBAC enforcement

Critical vulnerability fixes:
- commands/list.rs: Add deployment ownership check before listing
- commands/get.rs: Add deployment ownership check before fetching
- agent/enqueue.rs: Verify user owns deployment before enqueuing
- pipe/list.rs: Filter templates by user (own + public only)
- pipe/list.rs: Verify deployment ownership for instance listing
- pipe/get.rs: Check template ownership or is_public before returning
- pipe/get.rs: Verify deployment ownership for instance detail
- pipe/delete.rs: Check ownership before deleting templates/instances
- pipe/create.rs: Verify deployment ownership for instance creation
- db/pipe.rs: Add list_templates_for_user() with user_id filter

Multi-user test infrastructure (tests/common/mod.rs):
- spawn_app_two_users() with token-aware mock auth
- USER_A/USER_B constants for owner/attacker pattern
- Helper functions: create_test_cloud, create_test_deployment, etc.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- project::fetch_one_by_name: add user_id filter (prevents cross-user name lookup)
- project::delete: add user_id to WHERE clause
- cloud::delete: add user_id to WHERE clause
- server::delete: add user_id to WHERE clause
- All callers updated to pass user.id
- Returns rows_affected > 0 instead of always true
- Added .sqlx/ cache for updated fetch_one_by_name query

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… endpoint

Pipe feature Phase 1 implementation:

CLI commands (src/bin/stacker.rs, src/console/commands/cli/pipe.rs):
- pipe list: queries API, displays table with ID/source/target/status/triggers/errors
- pipe create: interactive flow — scans both apps, lets user pick endpoints,
  auto-matches fields, creates template + instance via API
- pipe activate: sets status to active, sends activate_pipe agent command
  with full pipe config (endpoints, field mapping, trigger type)
- pipe deactivate: sets status to paused, sends deactivate_pipe agent command
- pipe trigger: one-shot execution, sends trigger_pipe with optional input data

Client methods (src/cli/stacker_client.rs):
- 6 new methods: list_pipe_instances, get_pipe_instance, create_pipe_template,
  create_pipe_instance, update_pipe_status, list_pipe_templates
- 4 new structs: PipeTemplateInfo, PipeInstanceInfo,
  CreatePipeTemplateApiRequest, CreatePipeInstanceApiRequest

Agent command types (src/forms/status_panel.rs):
- activate_pipe, deactivate_pipe, trigger_pipe command request/report structs
- Full parameter validation and result validation
- 9 unit tests for all new command types

REST endpoint (src/routes/pipe/update.rs):
- PUT /api/v1/pipes/instances/{id}/status — update pipe instance status

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comprehensive security tests for every API endpoint the stacker CLI hits:

- list projects: user isolation (3 vs 1), unauthenticated rejected
- list clouds: user isolation, cross-user GET rejected
- list servers: user isolation, cross-user GET rejected
- list deployments: user isolation, cross-user by-hash/by-id rejected
- deploy: cross-user project rejected, cross-user cloud creds rejected
- destroy: cross-user force-complete rejected, owner allowed
- enqueue command: cross-user deployment rejected
- delete project/cloud/server: cross-user rejected
- unauthenticated access: all list endpoints reject

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@vsilent vsilent merged commit 75cc872 into main Apr 10, 2026
14 of 16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant