Security & 2FA
A workspace eventually holds your Stripe API keys, your OAuth tokens for Google Analytics, your webhook secrets, and a list of every customer you've ever charged. Treat the account that owns it like production access. This page covers how sign-in, sessions, and credential storage work — and how to export or delete everything.
Sign-in methods
Four ways in: email + password, Google, Apple, and GitHub. You can attach several to one account — from Settings → Security → Connected accounts, link or unlink any social provider. Ploxir refuses to disconnect your only sign-in method: to remove your last social login, set a password first via Change password, then unlink.
Adding or removing a sign-in method fires a security alert to your email — linking a new identity to a live account is a classic backdoor vector, so it's never silent.
New accounts created with email + password must verify their email before entering the dashboard (the link is good for 24 hours; sign in again to get a resend option). Social signups skip this step — Google, Apple, and GitHub have already verified the address.
Sessions
Sessions are server-signed JWT cookies. A session lasts 8 hours and renews on a rolling basis — roughly every hour of activity extends it. Stay active and you stay signed in; walk away for 8 hours and you're signed out.
Signing out (user menu → Sign out) clears the session on that device only. To sign out everywhere at once, reset your password: every session that existed before the reset — including a hijacked one — is invalidated within about 5 minutes (each session re-checks its validity against the server on that interval).
Passwords & resets
Passwords are stored as bcrypt hashes — never in plaintext, never recoverable. There is no "change password" form that asks for the old one; both "forgot" and "change" go through the same emailed reset link from /forgot-password.
- The reset link is single-use and expires after 1 hour.
- Only a sha256 hash of the token is stored — a database leak can't be turned into working reset links.
- Completing a reset invalidates every existing session (see above) and emails you a password-changed confirmation.
- Sign-in and reset endpoints are rate-limited against brute force.
Changing your email address is similarly gated: the change only commits when you click a confirmation link sent to the new address, and the old address gets a security alert — so a hijacker can't silently re-point your login identity.
Two-factor authentication (TOTP)
From Settings → Security, click Enable two-factor authentication. Scan the QR code with any TOTP app (1Password, Authy, Google Authenticator, Bitwarden, Aegis, …) and confirm with the 6-digit code. Nothing is saved until that first code verifies — abandoning setup halfway leaves 2FA off.
On success you get 10 single-use backup codes, shown once. Save them somewhere safe — they're your way back in if you lose your authenticator. At sign-in, the 2FA prompt accepts either the 6-digit code or a backup code; each backup code works exactly once. When one is used, you get an email telling you how many remain.
Disabling 2FA requires a current TOTP code or a backup code — proof you're physically holding the second factor. Enabling and disabling each trigger an email notification.
Security alerts
Account-security events always reach you by email, and most also appear in the in-app notification bell. This category can't be muted in notification preferences. You'll hear about:
- New-device sign-in — a password sign-in from a device we haven't seen before, with the browser/OS and IP address.
- Sign-in method added or removed — Google / Apple / GitHub linked or unlinked.
- Password changed.
- Email-change requested — alert to the old address, confirmation to the new.
- 2FA enabled or disabled.
- Backup code used — including how many codes you have left.
If any of these arrive and it wasn't you: reset your password immediately (that kills every existing session), then review your connected accounts and 2FA state.
How Ploxir stores your credentials
Every connector API key and OAuth token is encrypted with AES-256-GCM before it touches the database. The encryption key lives in the process environment, never in the database — a database dump alone can't decrypt anything. Key rotation is versioned: a new key can be introduced and a compromised one retired without re-encrypting everything in place. TOTP secrets are encrypted at rest the same way.
Encrypted credential blobs never travel the page-render path — dashboard queries select only the fields needed to draw widgets, so a source's secrets are never embedded in the HTML your browser receives. Decryption happens server-side, only at sync time.
Sync error messages are scrubbed before being stored or displayed: anything that looks like an API key or a Bearer token is redacted, so a provider echoing your key back in an error can't leak it into the UI.
Webhook secrets
For custom webhook sources, the URL path is the credential — anyone who knows it can POST events. Accordingly:
- Revealing or copying a webhook URL requires the Admin or Owner role. Editors and Viewers never see the secret — it's stripped from the page data they receive, not merely hidden.
- The reveal is fetched on demand when an admin clicks — the URL is never sitting in the initial HTML.
- You can add an optional second factor: an HMAC signing secret that makes Ploxir verify a signature and timestamp on every delivery. See Webhooks for the signing spec.
Roles & access control
Every workspace has four roles — Owner > Admin > Editor > Viewer — and every action is permission-checked on the server, per request. Hiding a button is cosmetic; the enforcement is in the action itself, so a crafted request from a Viewer fails exactly like a missing button. Workspace isolation is re-checked inside every mutation too — no role in workspace A grants anything in workspace B. See Concepts for the full role reference.
Your data: export & deletion (GDPR)
Both live under Settings → Security → Your data & account.
Export
Download my data assembles a JSON file with your account profile, sign-in providers, known devices, recent notifications, and the metadata of every workspace, project, and source you belong to. Secrets, API keys, and encrypted source configs are deliberately excluded — the export can't be used to steal your credentials.
Deletion
Delete my account schedules permanent deletion after a 7-day grace period. You can cancel any time before then from the same page; you get an email when deletion is scheduled and when it executes. After the grace period:
- Your Stripe customer is deleted — any subscription is cancelled and your card and billing details are removed from Stripe, not just from Ploxir.
- Workspaces where you're the only member are deleted with you.
- Workspaces you own that have other members are preserved — ownership transfers to the highest-ranked remaining member, so your teammates' data isn't destroyed because you left.
- Your user row, devices, notifications, and memberships are hard-deleted.
What we never store
- Plaintext passwords — bcrypt hashes only.
- Plaintext connector credentials — AES-256-GCM encrypted, key outside the database.
- Raw reset / verification tokens — sha256 hashes only; the plaintext exists solely in the email we send.
- Plaintext backup codes or TOTP secrets — codes are bcrypt-hashed, secrets encrypted at rest.
- Card numbers — payment details live in Stripe; Ploxir never sees or stores them.
- API keys inside error logs — provider errors are scrubbed of anything key-shaped before persisting.
Reporting a vulnerability
Found something? Email [email protected] with steps to reproduce, and please don't test against workspaces you don't own.
FAQ
How do I sign out of all devices at once?
Reset your password. Every session created before the reset is invalidated within about 5 minutes — including sessions on devices you no longer control. There's no separate "sign out everywhere" button; the password reset is that button.
I lost my authenticator. How do I get back in?
Use one of your backup codes at the 2FA prompt — the code field accepts either. Once in, disable 2FA with another backup code and re-enroll with your new device (which issues a fresh set of 10). If you've lost the authenticator and all backup codes, contact [email protected] — there is deliberately no self-service bypass.
Does 2FA cover all my workspaces?
Yes. 2FA is an account-level setting — it protects your sign-in, and your sign-in is the door to every workspace you belong to. There is no per-workspace 2FA toggle, and a workspace can't require its members to enable it (yet).
Can I see a list of devices that are signed in?
Not as a management UI — there's no per-device "revoke" button. Devices surface two ways: a security alert whenever a password sign-in comes from an unrecognized device, and the known-device list included in your data export. To evict a specific device, reset your password (signs out everything) and sign back in.
Can Editors or Viewers see our API keys?
No. Connector credentials are never sent to any browser — they're decrypted server-side at sync time only. Webhook URLs (which are themselves credentials) are revealed on demand to Admins and Owners only; for everyone else the secret is stripped from the page data entirely.
What exactly is in the data export?
Your account profile (email, name, plan, 2FA status, sign-in providers), known devices, your most recent notifications, and the name/slug/creation metadata of your workspaces, projects, and connected sources. It intentionally excludes API keys, OAuth tokens, webhook secrets, and encrypted configs.
What happens to my team's workspace if I delete my account?
It survives. Any owned workspace with other members transfers ownership to the highest-ranked remaining member during deletion. Note the workspace then runs on the new owner's plan limits (see Plans & billing). Only workspaces where you were the sole member are deleted with the account.
Does deleting my account cancel my subscription?
Yes — and more than cancel. Deletion removes the Stripe customer object itself, which ends the subscription and erases your card and billing details from Stripe. Deleting a workspace, by contrast, never touches billing.
I clicked "Delete my account" by mistake. Can I undo it?
Yes, for 7 days. Deletion is scheduled, not immediate — go back to Settings → Security and cancel it any time within the grace window. You'll have received an email with the scheduled date; a second email confirms the cancellation.
