Skip to content

fix: require authentication by default in standalone mode#431

Open
ambient-code[bot] wants to merge 4 commits intomainfrom
fix/356-standalone-auth-default
Open

fix: require authentication by default in standalone mode#431
ambient-code[bot] wants to merge 4 commits intomainfrom
fix/356-standalone-auth-default

Conversation

@ambient-code
Copy link
Copy Markdown
Contributor

@ambient-code ambient-code Bot commented Apr 8, 2026

Summary

Fixes #356 — standalone mode previously exposed an unauthenticated, unencrypted gRPC server by default.

  • Auto-generate a random passphrase (via secrets.token_urlsafe(32)) when --passphrase is not provided in standalone mode, printed to stderr for sharing with clients
  • Add --unsafe-no-auth flag to explicitly disable authentication (mutually exclusive with --passphrase)
  • Emit warnings when --unsafe-no-auth is used, with a stronger warning when combined with --tls-grpc-insecure
  • Reword pre-existing misleading warning about passphrase and TLS to clarify that passphrase auth IS active even without TLS

Test plan

  • Existing CLI tests pass
  • Lint passes (make lint-fix)
  • E2e tests ported to Go + Ginkgo framework (matching upstream migration from BATS)
  • E2e: --unsafe-no-auth allows unauthenticated access
  • E2e: auto-generated passphrase is printed to stderr and can be used to connect (includes negative test with wrong passphrase)
  • E2e: --passphrase and --unsafe-no-auth are mutually exclusive
  • Manual: jmp run --exporter myconfig --tls-grpc-listener 1234 --tls-grpc-insecure now auto-generates and prints a passphrase
  • Manual: jmp run --exporter myconfig --tls-grpc-listener 1234 --tls-grpc-insecure --unsafe-no-auth warns but allows unauthenticated access
  • Manual: --passphrase and --unsafe-no-auth together produces a UsageError

🤖 Generated with Claude Code

@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 8, 2026

Deploy Preview for jumpstarter-docs ready!

Name Link
🔨 Latest commit 212677f
🔍 Latest deploy log https://app.netlify.com/projects/jumpstarter-docs/deploys/69d6d115232b570008dfb3a4
😎 Deploy Preview https://deploy-preview-431--jumpstarter-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 8, 2026

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 741f5e17-ec32-49f3-abf4-c39fd5ba0d0b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/356-standalone-auth-default

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mangelajo
Copy link
Copy Markdown
Member

@ambient-code you need to update the e2e tests most probably...

@ambient-code
Copy link
Copy Markdown
Contributor Author

ambient-code Bot commented Apr 8, 2026

Updated the e2e tests in e2e/tests-direct-listener.bats to work with the new auth-by-default behavior:

  1. Fixed existing tests: The _start_exporter helper now passes --unsafe-no-auth when no passphrase is provided, so tests that previously ran without authentication continue to work.

  2. Added new tests:

    • --unsafe-no-auth allows unauthenticated access - verifies the flag works as expected
    • auto-generated passphrase is printed to stderr - verifies the auto-generated passphrase is printed and can be used to connect
    • --passphrase and --unsafe-no-auth are mutually exclusive - verifies the mutual exclusivity validation

Commit: a25a70f

@ambient-code
Copy link
Copy Markdown
Contributor Author

ambient-code Bot commented Apr 8, 2026

Status Update

Reviewed the PR and its current state:

Comments: The only actionable comment was from @mangelajo requesting e2e test updates. This was addressed in commit a25a70f which:

  • Updated the _start_exporter helper to pass --unsafe-no-auth when no passphrase is provided
  • Added three new tests covering: --unsafe-no-auth flag, auto-generated passphrase output, and --passphrase/--unsafe-no-auth mutual exclusivity

CI: No failures so far. Several checks have passed (lint-python, typos, pytest-matrix ubuntu 3.11/3.12, e2e-compat-old-client). Some checks are still pending (e2e-tests, macOS pytest-matrix runs). Will need to confirm once those complete.

Code review notes:

  • The implementation in run.py looks correct: auto-generates a passphrase via secrets.token_urlsafe(32), prints it to stderr, and provides --unsafe-no-auth as an explicit opt-out
  • Proper mutual exclusivity validation between --passphrase and --unsafe-no-auth
  • Appropriate warning messages for unsafe configurations
  • No further code changes appear needed at this time

No fixes required -- waiting on remaining CI checks to complete.

Comment thread e2e/tests-direct-listener.bats Outdated
--tls-grpc-listener "$LISTENER_PORT" \
--tls-grpc-insecure 2>"${BATS_TEST_TMPDIR}/exporter.log" &
LISTENER_PID=$!
echo "$LISTENER_PID" > "${BATS_TEST_TMPDIR}/exporter.pid"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is the lifecycle of this exporter handled , will something kill it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exporter's lifecycle is managed by the existing teardown() function (line 96), which calls stop_exporter(). The test writes the PID to ${BATS_TEST_TMPDIR}/exporter.pid (line 193), and stop_exporter() reads that file, kills the process, waits for it, and removes the PID file. This is the same mechanism used by all other tests in this file via _start_exporter().

@raballew raballew self-requested a review April 13, 2026 17:11
Comment thread e2e/tests-direct-listener.bats Outdated
Comment thread python/packages/jumpstarter-cli/jumpstarter_cli/run.py
Comment thread e2e/tests-direct-listener.bats Outdated
@ambient-code
Copy link
Copy Markdown
Contributor Author

ambient-code Bot commented Apr 13, 2026

Review feedback addressed

Addressed 3 review comments from @raballew (commit 3deeba7):

1. Missing negative test for auto-generated passphrase (MEDIUM) -- Agreed and fixed.
Added a negative test within the auto-generated passphrase is printed to stderr test that attempts to connect with a wrong passphrase and asserts failure. This closes the coverage gap for the auto-generated passphrase enforcement path.

2. Pre-existing misleading warning (MEDIUM) -- Agreed and fixed.
Reworded the warning from --passphrase has no effect without TLS to passphrase authentication is active but TLS is disabled. The old wording was inaccurate since PassphraseInterceptor is unconditionally added when a passphrase is set, regardless of TLS. With auto-generated passphrases now being the default, this misleading message would fire more frequently and could lead users to add --unsafe-no-auth unnecessarily.

3. Fragile passphrase extraction (LOW) -- Acknowledged as a nit. The coupling between the sed pattern and the message format is acceptable since we control both sides. No code change needed.

CI: All checks passing prior to this push.

Ambient Code Bot and others added 3 commits April 14, 2026 08:46
Standalone mode previously defaulted to no passphrase, exposing an
unauthenticated gRPC server. Now a random passphrase is auto-generated
when --passphrase is not provided. Users must pass --unsafe-no-auth to
explicitly disable authentication.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Existing tests that ran without authentication now use --unsafe-no-auth
since the exporter auto-generates a passphrase when neither --passphrase
nor --unsafe-no-auth is provided. Also adds tests for auto-generated
passphrase output, --unsafe-no-auth flag, and mutual exclusivity of
--passphrase and --unsafe-no-auth.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ading warning

Address review feedback from @raballew:
- Add negative test verifying wrong passphrase is rejected when using
  auto-generated passphrase (closes test coverage gap)
- Reword pre-existing warning to clarify that passphrase auth IS active
  even without TLS, but the passphrase is transmitted in plaintext

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ambient-code ambient-code Bot force-pushed the fix/356-standalone-auth-default branch from 3deeba7 to b60ee8e Compare April 14, 2026 08:48
@ambient-code
Copy link
Copy Markdown
Contributor Author

ambient-code Bot commented Apr 14, 2026

Rebased onto main to resolve merge conflict

The e2e/tests-direct-listener.bats file was deleted on main when e2e tests were migrated from BATS to Go + Ginkgo (commit e044198, d7a65e0). This PR had been modifying that file, causing a modify/delete conflict.

Resolution: Ported all auth-by-default e2e test changes to the new Go test framework:

  • e2e/test/utils.go: Updated StartDirectExporter to automatically pass --unsafe-no-auth when no passphrase is provided. Added StartDirectExporterAutoAuth helper for testing the auto-generated passphrase flow.

  • e2e/test/direct_listener_test.go: Added three new test cases:

    1. --unsafe-no-auth allows unauthenticated access -- verifies the explicit opt-out flag works
    2. auto-generated passphrase is printed to stderr and can be used to connect -- verifies the passphrase is printed, can be used to connect, and that a wrong passphrase is rejected (covers both positive and negative paths)
    3. --passphrase and --unsafe-no-auth are mutually exclusive -- verifies the validation

The run.py changes (core auth-by-default logic, --unsafe-no-auth flag, warning rewording) were rebased cleanly with no conflicts.

Copy link
Copy Markdown
Member

@raballew raballew left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All three previous review concerns have been addressed.

  1. Negative test for auto-generated passphrase - resolved. The test now verifies that a wrong passphrase is rejected after auto-generation (lines 211-214 of direct_listener_test.go).

  2. Misleading warning reworded - resolved. The warning now reads "passphrase authentication is active but TLS is disabled" instead of the previous inaccurate phrasing.

  3. Fragile passphrase extraction - acknowledged. The Go test uses SplitN with a non-empty assertion, which is acceptable.

One minor observation noted inline. The core logic is sound: auto-generation is scoped to standalone mode only, validation is correct, and the security model (hmac.compare_digest, tiered warnings) is well implemented.

AI-generated review

Comment thread e2e/test/utils.go
…tion

Reset pt.logs in StopAll() so that stale stderr data from earlier tests
does not persist across test boundaries, avoiding confusion when
debugging test failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ambient-code
Copy link
Copy Markdown
Contributor Author

ambient-code Bot commented Apr 15, 2026

Review feedback addressed (round 3)

Addressed 1 review comment from @raballew (commit 2e6e038):

Shared stderr buffer accumulates data across tests (LOW) -- Agreed and fixed.
Added pt.logs = make(map[string]*logBuffer) to StopAll() so that stale stderr data from earlier tests is cleared between test runs. This prevents accumulated buffer data from causing confusion when debugging future test failures.

CI: All checks were passing prior to this push.

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.

Standalone mode unauthenticated by default

2 participants