npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

strapi-plugin-shieldauth

v0.1.12

Published

Multi-factor authentication for Strapi v5 admin panel with license-gated Pro features.

Readme

ShieldAuth — MFA for Strapi v5

Secure your Strapi v5 admin panel with modern multi-factor authentication.

ShieldAuth ships with TOTP and recovery codes today, with Email OTP, SMS, and WebAuthn on the roadmap. All paid factors are unlocked by your ShieldAuth license — the plugin validates your key against the ShieldAuth backend on startup and once per hour thereafter.


✅ Requirements

| | | |---|---| | Strapi | v5.x | | Node.js | ≥ 20 (the plugin uses native fetch and crypto.randomUUID) | | Database | Any Strapi-supported DB (Postgres, MySQL, SQLite). The plugin's instanceId is persisted to your DB — see Seats & instanceId. | | ShieldAuth account | A license key issued from your ShieldAuth dashboard | | Outbound HTTPS | Strapi must be able to reach the ShieldAuth backend |


🚀 Install

npm install strapi-plugin-shieldauth

⚙️ 1. Register the plugin

Add to your Strapi config/plugins.ts (or config/plugins.js):

export default ({ env }) => ({
  shieldauth: {
    enabled: true,
    config: {
      // Optional — you can also paste the key in the admin UI.
      licenseKey: env('SHIELDAUTH_LICENSE_KEY'),
      // Shown in TOTP authenticator apps (Google Authenticator, 1Password, etc.).
      appName: 'My Strapi App',
      issuer: 'My Company',
    },
  },
});

That's the entire plugin config. Everything else (license key, encryption key) is read from environment variables — keep them out of source control.


🔐 2. Set environment variables

Add these to your .env:

# Your license key. Get it from your ShieldAuth dashboard.
# You can leave this blank and paste the key in the admin UI instead — both work.
SHIELDAUTH_LICENSE_KEY=

# Strongly recommended — encrypts TOTP secrets at rest (AES-256-GCM).
# Generate with:  openssl rand -hex 32
# ⚠️  Changing this value AFTER users enroll will invalidate every TOTP setup.
SHIELDAUTH_ENCRYPTION_KEY=

What each variable does

| Variable | Required | Source | Notes | |---|---|---|---| | SHIELDAUTH_LICENSE_KEY | ❌ optional | ShieldAuth dashboard | Either set it here (good for Docker/CI) or paste it in the admin UI (good for first-time setup). The admin-UI value always wins if both are set. Treat the key as a secret — it authenticates every API call. | | SHIELDAUTH_ENCRYPTION_KEY | ❌ optional | You generate it | If unset, falls back to Strapi's admin.auth.secret. Set a dedicated value so rotating Strapi's admin secret doesn't break your TOTP enrollments. |


▶️ 3. Start Strapi and verify

npm run develop

Watch the logs for one of:

[shieldauth] License valid — plan=<your-plan> source=remote        ← all good
[shieldauth] License INVALID — No license key configured. ...       ← paste key in admin UI
[shieldauth] License backend rejected our Authorization header (...)← see Troubleshooting

If you didn't set SHIELDAUTH_LICENSE_KEY, open http://localhost:1337/admin, go to Settings → ShieldAuth → License, and paste your key. Validation runs immediately and the status panel updates.


🔑 4. Enroll your first admin

Once the license shows valid:

  1. Open the admin panel and go to Settings → ShieldAuth → My MFA Devices.
  2. Click Enroll TOTP, scan the QR code with your authenticator app.
  3. Confirm with a 6-digit code from the app.
  4. Save your recovery codes — they're shown once and you'll need them if you lose your authenticator.
  5. Log out, log back in. You'll be prompted for a TOTP code after entering your password.

🪪 Seats & instanceId

Every plugin install generates a UUID (instanceId) on first startup and persists it to your Strapi DB. The ShieldAuth backend counts each unique instanceId against your seat allowance.

Important:

  • The same Strapi DB = the same instanceId = one seat. Restart, redeploy, scale horizontally — all fine, no seat consumed.
  • A fresh Strapi DB (new project, wiped DB, ephemeral container without persistence) generates a new instanceId and consumes a new seat. If you're stress-testing or rebuilding environments, you may hit instance-limit-exceeded.
  • To free a seat: clear the license key in the admin UI, or click Release this install. Both call the backend's deactivate endpoint.

🛠️ Troubleshooting

| Symptom | Likely cause | Fix | |---|---|---| | Logs: code=missing-authorization | No license key configured | Paste your key in the admin UI or set SHIELDAUTH_LICENSE_KEY. | | Logs: code=invalid-scheme or code=invalid-key-format | License key is malformed (truncated copy/paste, extra whitespace) | Re-copy from your dashboard, paste again. | | Validation returns reason: "not-found" | Key doesn't exist on the backend | Check for typos. Make sure you copied the full key. | | Validation returns reason: "revoked" | Key was revoked by ShieldAuth admin | Contact support. | | Validation returns reason: "expired" | License past its renewal date | Renew on the ShieldAuth dashboard; refresh in admin UI. | | Validation returns reason: "instance-limit-exceeded" | More installs are claiming seats than your plan allows | Deactivate an unused install (admin UI → Release this install) or upgrade your plan. | | All TOTP logins suddenly fail with "invalid code" after a redeploy | SHIELDAUTH_ENCRYPTION_KEY changed | Restore the previous key value. If genuinely lost, every user must re-enroll TOTP. | | Backend unreachable, logs reason: "offline-fallback" | Network outage between your Strapi server and ShieldAuth | Plugin uses the last cached license result for ~1 hour. Fix connectivity; the plugin retries with 1m → 5m → 15m backoff. |


🔄 Rotating secrets

| Secret | How to rotate | |---|---| | SHIELDAUTH_LICENSE_KEY | Update env var (or admin UI) → plugin re-validates immediately. Old key continues to work until you either deactivate the seat or the SaaS revokes it. | | SHIELDAUTH_ENCRYPTION_KEY | Don't, casually. Changing this invalidates all TOTP enrollments. If you must, plan a maintenance window: rotate, then ask all users to re-enroll. |


🧹 Uninstalling cleanly

To uninstall in a way that frees the seat for reuse:

  1. In the admin UI: Settings → ShieldAuth → License → Clear license key. The plugin calls the deactivate endpoint and frees your seat before clearing the local key.
  2. Remove the plugin from config/plugins.ts.
  3. npm uninstall strapi-plugin-shieldauth.

If you skip step 1 — for example, you delete the project without clearing the key — the seat stays attached to that orphaned instanceId. Contact ShieldAuth support to release it.


✨ Features

  • Time-based One-Time Password (TOTP) — RFC 6238
  • Recovery codes (single-use, one-time-shown)
  • AES-256-GCM encryption of TOTP secrets at rest
  • Replay protection on TOTP verification
  • Rate limiting on authentication attempts
  • One-time login nonce (secure step-up flow)
  • Pluggable factor registry (Email OTP / SMS / WebAuthn coming)
  • License-driven feature gating

🔒 License & support

ShieldAuth is a commercial plugin.

  • A valid license key is required.
  • License validation runs on every Strapi startup and once per hour thereafter.
  • Unauthorized usage, redistribution, or modification is prohibited.

For licenses, billing, or support: 👉 [email protected]


📄 License

Proprietary — see the LICENSE file.