Portal Security
Magic-link sign-in, two-factor authentication, IP lock, and re-authentication for destructive actions at sheetlinkwp.com/account/.
Overview
The customer portal at sheetlinkwp.com/account/ is the only place you manage billing, sites, and add-ons outside of the WordPress admin. Because every action you take there affects what your sites can do - including cancelling subscriptions and deactivating client sites - the portal uses several layers of account protection.
None of this requires a WordPress login. Your WordPress install has its own separate security model; the portal is independent.
The four security layers, in the order they protect you:
- Magic-link sign-in - an email is the only way in. There are no passwords to leak.
- Two-factor authentication (optional) - TOTP code from an authenticator app required after the magic link.
- IP lock (optional) - reject requests from IP addresses different from the one that started your session.
- Re-authentication - destructive actions require a fresh emailed 6-digit code on top of the session.
Magic-link sign-in
Enter your purchase email on the portal sign-in screen. We send a one-time link that expires in 15 minutes and can only be used once. Clicking it signs you in and drops a secure HttpOnly session cookie valid for 7 days.
What the link looks like behind the scenes:
- 256-bit random token, hashed with SHA-256 before being stored in our database.
- We never log or email you a recoverable copy of the token.
- If the link expires, is already used, or is tampered with, you get bounced back to the sign-in page with an explanation.
Enumeration protection: whether or not an account exists for the email you enter, the portal always responds with "check your inbox." A malicious third party probing the site won't learn which emails have accounts.
Rate limits: 5 sign-in link requests per email per 15 minutes, 30 per IP per hour, 20 link-verification attempts per IP per hour.
Two-factor authentication (2FA)
Optional but strongly recommended for Agency and Enterprise tiers where a single cancelled subscription affects dozens of client sites.
Enroll: Security tab → Enable 2FA. Scan the QR code with any TOTP-compatible authenticator app - Google Authenticator, 1Password, Authy, Bitwarden, Microsoft Authenticator, etc. Enter a code from the app to confirm. You'll receive 10 single-use backup codes - save them immediately, they're shown only once.
After enrollment: every sign-in requires your 6-digit authenticator code (or one of the backup codes) after the magic link. Sessions in the pending-2FA state can't access the dashboard until the code is entered.
Disable: requires your current 2FA code and a fresh email re-auth code. This prevents an attacker with a hijacked session cookie from flipping 2FA off to gain persistent access.
How the secret is stored: AES-256-GCM encrypted at rest with a dedicated key. We never store the plaintext secret or any codes you've used.
Lost your authenticator? Use one of the 10 backup codes at the 2FA prompt. Each works once. If you're out of backup codes, contact support at sheetlinkwp.com/contact - we'll verify your identity and reset 2FA manually.
IP lock
Optional per-license setting that rejects portal requests from an IP address different from the one you signed in with. Useful for agencies working from a static office IP or a VPN.
Three modes:
- Off (default) - no check.
- Relaxed - current IP must be in the same /24 (IPv4) or /64 (IPv6) as the session-origin IP. Tolerates network-level NAT and DHCP churn.
- Strict - current IP must exactly match session-origin IP. Use only if you have a truly static IP.
When a request is rejected because of an IP mismatch, the portal asks you to sign in again via a fresh magic link. The new session records the new IP as its origin.
Multi-license accounts: if you have both a Freelancer license (off) and an Agency license (strict), the stricter setting wins for all portal actions.
Changing the mode requires a fresh email re-auth code - so an attacker who hijacked your session can't disable the lock from the inside.
Re-authentication for destructive actions
Actions that can't be easily undone ask for a one-time 6-digit code before they run, even if you're already signed in:
- Cancelling a subscription (add-on or monthly plan)
- Cancelling a monthly plan
- Deactivating a client site on an Agency/Enterprise license
- Disabling 2FA
- Changing IP lock mode
- Adding or rotating a subscription-change webhook
Click the destructive button in the portal and you'll get a modal prompt: "We sent a 6-digit code to your email." Enter the code, and the action proceeds. The code expires in 5 minutes and can only be used once.
This protects you against a scenario where an attacker got control of the session cookie (via XSS on a third-party site, stolen laptop, etc.). Without access to your email inbox, they can't trigger the destructive code paths.
Rate limits: 5 re-auth code requests per session per hour, 10 code-entry attempts per session per hour.
Sign out everywhere
If you suspect a session has been compromised, the Sign out button in the header revokes the current session. For a hard reset, send a request to the /auth/signout endpoint with {"allDevices": true} - this revokes every active session on the account. (A "sign out of all devices" button is coming to the Security tab.)
After revoking sessions, rotate 2FA (disable then re-enable to get fresh backup codes) if you think the attacker may have captured any codes.
Audit log
Every portal action - sign-in attempt, subscription change, cancellation, 2FA enrollment, IP lock mode change - is recorded with timestamp, IP, and user-agent. Audit records are retained for 90 days.
If you believe your account has been misused, contact support and reference the time window - we can pull the audit trail for your account.
Ready to Get Started?
Install SheetLink Forms and connect your first form in under 10 minutes.