Skip to content

Password Protection

Nix edited this page May 27, 2026 · 3 revisions

Password Protection

Password protection is optional per public link.

When enabled, visitors must enter the password before GhostlyShare forwards traffic to the selected local app.

Password protection applies to both random URLs and custom domains. In the desktop app, it can be configured before sharing starts or while the link is live. In the CLI, password protection is configured when ghs share starts.

When To Use It

Password protection is useful for:

  • Private demos.
  • Temporary reviews.
  • Quick tests with a small group.
  • Sharing work that should not be casually opened by anyone with the link.

The password should not be shared publicly or posted in GitHub issues.

Password Rules

Passwords must be 8 to 32 characters. There is no special complexity rule, but an empty or whitespace-only password is rejected.

GhostlyShare does not store the visitor-facing password as plain text in the tunnel configuration. It creates a salted PBKDF2-SHA256 hash for verification while the link is running. In the desktop app, the current runtime password can be kept in memory for the current app session so it can be copied or reused while GhostlyShare is open.

Desktop Live Changes

In the desktop app, the key button opens the password protection settings in both local-only and live states.

While a link is live, you can:

  • Enable password protection for the current public link.
  • Change the password or failed-attempt limit.
  • Change the visitor password-session duration.
  • Remove password protection again.

Live changes apply immediately without restarting the tunnel. Existing HTTP or WebSocket connections are not forcibly closed, but new requests use the updated password rules.

When password protection is changed or removed, GhostlyShare rotates the route session. Existing visitor password cookies for the previous settings are no longer valid.

Visitor Login Flow

When a visitor opens a password-protected public URL without a valid password session:

  • Browser navigation receives a GhostlyShare password page.
  • API-style requests receive 401 with application/problem+json.
  • GhostlyShare does not forward the request to the local app until the password is accepted.

After the correct password is submitted, GhostlyShare redirects the visitor back to the requested path and sets a temporary ghostlyshare_access cookie. The cookie is HttpOnly, Secure, SameSite=Lax, and scoped to /.

The cookie value is signed for the current tunnel route and includes the expiration time. Editing the cookie or changing the expiration invalidates it.

Failed Attempts and Lockout

By default, 3 wrong passwords from the same visitor lock that visitor out for 5 minutes. The desktop app lets you choose 3 to 10 failed attempts. The CLI uses --password-attempts <number> with the same 3 to 10 range.

During lockout:

  • GhostlyShare returns 429 Too Many Requests.
  • Responses include Retry-After: 300.
  • A correct password is still blocked until the 5-minute lockout expires.

Successful login resets the failed-attempt counter for that visitor.

The visitor identity is based on request headers when available: Cloudflare's connecting IP header first, then forwarded IP headers, then a non-loopback remote IP. If no IP is available, GhostlyShare falls back to the user agent, and finally to an anonymous route-local bucket. Attempt tracking is scoped to the current tunnel route session.

Password Session Expiration

The default successful password session is 30 minutes.

Desktop choices are:

  • 5 minutes.
  • 15 minutes.
  • 30 minutes.
  • 1 hour.
  • 4 hours.
  • 24 hours.

The CLI accepts any whole-minute value from 5 to 1440:

ghs share 5173 --password --password-session-minutes 60

Password sessions are not permanent and are not a user account. When the configured time expires, the visitor must enter the password again. Stopping and starting the link also creates a new tunnel route session, so old password cookies no longer authorize the new run.

Changing password settings while the desktop link is live also creates a new route session, so old password cookies no longer authorize new requests.

CLI Examples

Prompt securely and confirm the password:

ghs share 5173 --password

Read the password from an environment variable for scripts:

GHS_SHARE_PASSWORD="secret123" ghs share 5173 --password-env GHS_SHARE_PASSWORD

Set both visitor lockout threshold and password session length:

ghs share 5173 --password --password-attempts 5 --password-session-minutes 60

What Happens When Sharing Stops

Stopping the tunnel, stopping GhostlyShare, or stopping the local app ends the current public access path for that sharing session.

If you share the app again, check the current link and password state before sending it to anyone.

Limits

Password protection is not a full user-management system. It does not add roles, accounts, audit trails, or per-user permissions.

Use it as an extra protection layer for temporary sharing, not as a replacement for careful sharing and basic security habits. Do not expose sensitive, private, or internal services just because password protection is enabled.

Clone this wiki locally