Shield.
Trust center · Security overview

Security at Shield

Shield is built around a simple principle: the safest data is the data we don’t have. The source code you submit for obfuscation never lands on disk, and the rest of what we store is the minimum needed to run your account.

Source code never stored at restTLS 1.2+ on every endpointbcrypt password hashingSingle-session anti-account-sharingAudit log of every obfuscation

At a glance

This page describes Shield’s security posture in concrete detail. Each section answers a question you or your security team are likely to ask. If something is unclear, missing, or feels light, mail security@shieldmycode.com and we’ll respond within one business day.

What we store

Account metadata, plan + subscription status, aggregate usage counts, opaque API key hashes, tamper-event reports. Nothing else.

What we never store

The source code or HTML you submit for obfuscation. The protected output. Your card number. Any data not strictly required to run your account.

Where it runs

DigitalOcean infrastructure (SOC 2 Type II + ISO 27001). Postgres on the same host, encrypted at rest. Nginx + PM2 process management.

Where payments live

Stripe. Card data is collected by Stripe Elements directly inside their hardened iframe — it never touches our server. We see only the last 4 digits and brand.

How we handle your data

Our data minimization is deliberate. Every byte we hold is a byte that could be lost, leaked, or subpoenaed. We hold as little as possible to make Shield work.

Data we store

WhatDetailWhy
Account identifierUUID, email, hashed password (bcrypt cost 12), display name, username, optional avatar referenceAuthenticate you and address you correctly.
Plan & subscriptionPlan ID, subscription status, period dates, cancel-at-period-end flag — synced from Stripe via webhooksEnforce quotas and surface your billing state.
Usage metadataPer-obfuscation: timestamp, kind (JS/HTML), strictness level, byte counts, duration, anonymized 16-char IP hash. Bucketed per (user, calendar month).Quota accounting and the History view.
API key hashesSHA-256 of the secret portion only. The plaintext key is shown exactly once at creation time.Authenticate API requests without recoverable storage of secrets.
Telemetry eventsWhen you set a telemetry URL: reason code (integrity / debugger / headless / etc.), coarse geo, 16-char IP hash, user-agent substring. Hard-capped at 10,000 events per account; older events evicted automatically.Power the threat-intel dashboard.
GitHub connectionOptional. Your Personal Access Token, encrypted at rest with envelope encryption + AES-256.GitHub round-trip integration on Pro+ plans.
Stripe customer IDA pointer (cus_...) into Stripe. No card data ever stored on our side.Tie Shield account to Stripe customer.
Session recordsRandom 64-char session ID, user agent string, anonymized IP hash, last_seen timestamp. Hard expiry 30 days; idle expiry 10 minutes.Single-session policy enforcement.

Data we never store

  • Source code submitted for obfuscation. Processed in-memory in the obfuscation engine and discarded when the HTTP response completes.
  • Obfuscated output. Same path: returned to you in the response, not retained.
  • Card numbers, CVCs, expiry dates. Collected by Stripe Elements in a domain-isolated iframe; we receive only a tokenized PaymentMethod ID.
  • Plaintext API keys. Hashed at creation; the plaintext appears once on the screen and is then gone forever.
  • Plaintext passwords. bcrypt only, never logged.
  • Raw IP addresses. Hashed to a 16-character SHA-256 prefix at the moment of capture. The raw IP is not stored or logged.
Right of access & deletion: you can delete your account at any time from Dashboard → Profile. We retain billing records as legally required and a hashed copy of your prior email to prevent abuse re-registration. See our Privacy Policy for the complete data lifecycle.

We do not store your code

This is the question we’re asked most. The answer: source code submitted to Shield is processed in-memory and never written to disk or any database.

Concretely, the lifecycle of a single obfuscation request is:

  1. HTTPS request arrives at our Nginx reverse proxy
  2. Proxied to the Node.js process, which parses the JSON body into a JavaScript string in memory
  3. The obfuscation engine runs synchronously in that process. AST parsing, transforms, defense injection — all in memory.
  4. The protected output string is JSON-encoded into the HTTP response
  5. The response is flushed to the network
  6. The strings are garbage-collected when the request handler returns

Only the metadata of the request — timestamp, kind, level, byte counts, duration, anonymized IP hash, your user ID — is persisted to the audit log table. The source and output bytes are not.

This is verifiable against our source code. The relevant endpoint handlers (e.g. app/api/obfuscate/route.ts) hold the source in a parameter, pass it through the engine, return the result, and do not write it. We are happy to walk through this with your security team on request.

Account & authentication

Passwords

Passwords are hashed using bcrypt at cost factor 12, with a unique per-user salt. The plaintext is never logged or stored. We never compare passwords using string equality; comparisons happen through bcrypt’s timing-safe verification.

Sessions

Login creates a DB-backed session record with a cryptographically random 64-character session ID. AHttpOnly, SameSite=Lax, Secure cookie carries the ID; everything else (user_id, expires_at, user_agent, anonymized ip_hash, last_seen_at) lives in the database. Hard expiry: 30 days. Idle expiry: 10 minutes (rolling — any authenticated request slides the window).

Single-session anti-account-sharing: every successful login deletes all other sessions for that user. Two devices cannot be logged in simultaneously. Designed to deter password sharing across organizations.

GitHub OAuth (optional)

Sign in with GitHub uses OAuth 2.0. We request onlyread:user + user:email scopes — enough to identify and provision accounts, nothing else. The CSRF token is rotated per flow. Your GitHub access token from this flow is exchanged once for the user identity and then discarded. A separate, encrypted PAT is what we store if you opt into the GitHub round-trip integration (Pro+ plans only).

API keys

Each key is a 32-byte random token, base-prefixed withshield_. We store the SHA-256 hash of the secret portion only. The plaintext key is rendered to your browser exactly once — at creation — and then irretrievable. Lost keys cannot be recovered; they must be re-generated. Revoke any time from Dashboard → API keys.

Encryption

In transit

Every public endpoint serves over HTTPS with certificates rotated via Let’s Encrypt’s automated renewal (90-day cycle). Nginx is configured to accept TLS 1.2 and TLS 1.3 only. Strict Transport Security (HSTS) is published with a 6-month max-age and the includeSubDomains directive. Plain HTTP requests are redirected to HTTPS at the proxy layer.

At rest

Disk-level encryption is provided by DigitalOcean’s block-storage service, transparent to the application. Postgres data, Nginx logs, the application code itself, and the env file containing API secrets are all on encrypted volumes.

Application-level encryption is applied to sensitive secrets on top of disk encryption:

  • Passwords: bcrypt hash (one-way)
  • API keys: SHA-256 hash (one-way)
  • GitHub PATs: AES-256-GCM with an envelope key
  • Session IDs: not encrypted (entropy is the protection — 256 bits)

In memory

Sensitive values are not logged. The obfuscation engine receives source code strings and discards them when the request completes; we do not write them to stdout, stderr, or the database. Process memory is not deliberately zeroed (Node’s GC handles reclamation), which is a known trade-off documented here for completeness.

Application security

  • Input validation: every public API endpoint validates its request body against a Zod schema before any logic runs. Mismatches return a 400 with no further processing.
  • CSRF protection: the GitHub OAuth flow rotates a single-use CSRF token via HttpOnly cookie. Stripe checkout calls use session authentication; no cross-site form posts are accepted.
  • Rate limiting: the public playground (/api/try) enforces a per-IP quota (5 obfuscations / hour, 2 / minute, hashed IP). The authenticated APIs are gated by monthly plan quota.
  • Dependency scanning: GitHub Dependabot is enabled against our main repository. Vulnerable dependencies generate PRs we triage within one business day for high severity.
  • Secret management: environment variables live in /var/www/shield/.env.local on the droplet with file mode 0600. Stripe secret key, webhook secret, and GitHub OAuth credentials are never logged. We do not commit secrets to git.
  • Change management: every code change is in git history with author + timestamp. Deploys are scripted via a versioned installer.
  • Backups: Postgres is snapshotted by DigitalOcean’s automated daily backup. Retention: 7 days rolling. Restore tested quarterly.

Infrastructure

Shield runs on a single dedicated DigitalOcean droplet behind Cloudflare-protected DNS, with the following stack:

LayerTechnologyRole
DNSCloudflareDDoS protection, TLS edge, request inspection
TLS / proxyNginx 1.24HTTPS termination, gzip, reverse proxy to Node
App runtimeNode 20 + Next.js 15Application server, obfuscation engine, dashboard
Process supervisionPM2Restart on crash, log rotation, env injection
DatabasePostgreSQL 16Users, sessions, subscriptions, usage logs, telemetry events, API key hashes
ComputeDigitalOcean droplet (Ubuntu 24.04 LTS)Single-region, encrypted disk, daily snapshot

Single-region by design: we run in one DigitalOcean region for predictable latency and simpler compliance scope. Multi-region failover is on the Enterprise-tier roadmap.

Subprocessors

These are the third-party services Shield uses to operate. Each is a tier-1 vendor with their own current compliance attestations:

Payment processing, billing, customer portal

Data shared: Tokenized card / PaymentMethod IDs only — full card numbers never reach Shield. Customer email + name + Stripe customer ID.

PCI DSS Level 1SOC 1 Type IISOC 2 Type IIISO 27001
DigitalOcean
Trust page
Compute (droplet) + Postgres backups + DNS

Data shared: Everything on the application server, including the Postgres database.

SOC 2 Type IISOC 3ISO 27001ISO 27017ISO 27018CSA STAR Level 1
Cloudflare
Trust page
DNS, DDoS protection, edge TLS

Data shared: HTTP request metadata (no application data passes through unencrypted).

SOC 2 Type IIISO 27001PCI DSSFedRAMP Moderate
GitHub (Microsoft)
Trust page
Source code repository; OAuth identity provider

Data shared: Source code is on a private repository. OAuth identity (email + name) for users who sign in with GitHub.

SOC 1 Type IISOC 2 Type IIISO 27001ISO 27017ISO 27018
Let's Encrypt
Trust page
TLS certificate issuance

Data shared: Public DNS + ACME challenge data only. No customer or account data.

CA/Browser Forum baseline requirementsWebTrust audit

We do not currently use a transactional email provider, an analytics provider, or a CRM. If we add one, this list will be updated and any change communicated to existing customers with 30 days’ notice.

Compliance & certifications

We are transparent about where we are in the formal compliance lifecycle. Our security posture is mature; formal attestations are an ongoing investment.

SOC 2 Type II
Not currently attested

No third-party SOC 2 report at this time. The reason is deliberate: Shield’s data minimization (no customer source code stored, payment data offloaded to Stripe) reduces the audit scope dramatically vs typical SaaS, and we’ve prioritized engine + customer experience work that compounds faster. We pursue Type I scoping when a specific enterprise prospect requires it.

GDPR
Aligned

EU customers are supported. We act as data processor for any personal data you provide. Data subject access requests can be made via privacy@shieldmycode.com and are answered within 30 days. See Privacy Policy.

CCPA / CPRA
Aligned

California consumers have the same rights of access, deletion, and correction. Sale of personal information: we do not sell.

PCI DSS
Out of scope

Card data is collected by Stripe Elements directly in their hardened iframe and never touches our server. Stripe is PCI DSS Level 1 certified. The applicable Stripe SAQ-A pattern means our PCI scope is effectively zero.

HIPAA
Not applicable

Shield does not handle Protected Health Information. We are not currently set up to sign a Business Associate Agreement.

ISO 27001
Not currently certified

On the same roadmap as SOC 2 — pursued when a specific Enterprise lead requires it.

If your organization requires a specific compliance artifact to evaluate Shield, please contact sales@shieldmycode.com with the requirement and timeline.

Incident response

We follow a documented incident response process. The abbreviated version:

  1. Detect. Through monitoring, vulnerability disclosure, or customer report.
  2. Triage. Within one business hour of detection, classify severity (P0 — service down or data exposure; P1 — degraded; P2 — non-urgent).
  3. Contain. P0 / P1 incidents trigger immediate mitigation (block, rotate, take offline). Where customer credentials may be involved, we invalidate sessions.
  4. Eradicate & recover. Apply fix, restore service, validate.
  5. Notify. Affected customers receive direct email notification within 72 hours of incident confirmation. If the incident involves unauthorized access to personal data, we notify regulators where required by GDPR / CCPA.
  6. Post-mortem. A blameless post-mortem within 14 days of closure, with action items tracked to completion.
Status page: We do not currently operate a public status page. For any sustained service degradation, watch support@shieldmycode.com for proactive customer email.

Report a vulnerability

We welcome coordinated vulnerability disclosure. If you believe you’ve found a security issue in Shield, please contact us before publishing or sharing details:

Security contact
security@shieldmycode.com
  • · We acknowledge reports within one business day.
  • · Triage and severity assessment within five business days.
  • · We will not pursue legal action against good-faith researchers acting under coordinated disclosure.
  • · Public credit on this page (with your consent) for valid, in-scope reports.

Out of scope

  • Reports purely about missing security headers on marketing pages
  • Self-XSS that requires the victim to paste hostile code into their own console
  • Social engineering of Shield staff
  • DoS / volumetric attacks
  • Findings on third-party services (report those to the relevant vendor)
  • Theoretical concerns without a reproducible exploit

We do not currently offer a paid bug bounty. We acknowledge publicly and credit researchers who help us in good faith.

Shared responsibilities

Security is a shared-responsibility model. The table below lists what we do and what we expect you to do.

TopicShield’s responsibilityYour responsibility
Account passwordbcrypt hashing, lockout on abuseUse a strong, unique password; consider a password manager
API keysHashed at rest; one-time display at creationStore in your secret manager (1Password, env vars). Rotate when teammates leave.
Account sharingStrict single-session enforcementDo not share login credentials. Each user gets their own account.
GitHub PAT (Pro+)Encrypted at rest; revocable from dashboardUse a fine-grained PAT scoped to only the repos you intend to obfuscate. Revoke from GitHub anytime.
Telemetry endpoint URLPer-account, opaque token in the URLTreat as semi-secret. If leaked, attackers could spoof tamper events on your dashboard.
Obfuscation strictness selectionEngine ships every defense; sensible Hard preset by defaultMatch strictness to the value of what you're protecting. Test in a real browser before shipping production code.

Last reviewed: May 2026. This page is versioned in git and updated whenever our posture changes.

Security · Shield