Security

Last updated October 28, 2026

norc connects out, signs every write and edits only the crontab lines it created. Below is how, and what we don't have yet: SOC 2, ISO 27001, a pen test or a bug bounty.

norc doesn't hold SSH keys or SSH into your machines

There's no inbound access. You install a small agent on each machine you pair (the desktop app or the headless norc CLI daemon), and that agent makes an outbound-only connection to norc's relay, the same direction your browser talks to a website. Nobody connects in.

Every write that agent applies is authorized by a short-lived, single-use capability: a signed token (ES256 JWT) minted server-side, scoped to that one machine, that one job set, and a monotonic generation counter.The agent independently verifies the signature, audience, expiry, machine id, and a nonce before it touches anything. A replayed or forged token is rejected even if our servers were compromised.

On desktop, every write also requires a native Yes/No dialog the first time (sticky per machine after you approve it); on a headless server there's no one to prompt, so pairing itself is treated as standing consent, the same tradeoff you make installing any unattended agent.

Revoke access anytime from the vault's Machines page. Unpair stops the agent from accepting further writes immediately.

norc only ever touches the lines it wrote

Every job norc manages gets a tagged comment line (# norc: <id> <name>) directly above its crontab entry. Reconciliation matches strictly by that id: entries you wrote by hand, or that predate norc, show up as "unmanaged" and are left alone. norc will never silently edit or delete a line it didn't tag. Before any write is applied, it's round-tripped and re-parsed to confirm it produces exactly the intended set of tagged lines, with no injected or forged entries, control characters, or oversized fields.

You can verify this yourself, independent of the app: run norc jobs list on a paired machine to see exactly what norc thinks it owns, or just crontab -l before and after pairing to see the tagged lines norc adds. Nothing else in your crontab changes.

If norc goes down, your jobs keep running

Cron on your machine is what actually runs your jobs, on its own schedule, using its own local crontab. norc's cloud is a control plane that reads, writes, and syncs that crontab. It does not execute your jobs. If norc's relay or web app is unreachable, jobs already written to a machine's crontab keep firing exactly as scheduled; you just can't view or edit them from norc until the connection comes back. There's no SLA or uptime guarantee on norc's cloud services today (see Terms), but that's specifically because your jobs don't depend on it. Hosted schedulers that run jobs on their own servers can't say the same; see the comparison.

What norc encrypts, and what it doesn't

Your account password is hashed via Supabase Auth, never stored in plaintext. If you enable two-factor authentication, your TOTP secret is stored server-side (not end-to-end encrypted). If you bring your own key to AI Studio, that key is encrypted at rest with AES-GCM before storage. Job commands are encrypted at rest server-side (AES-GCM) before storage and decrypted only when read back by an authenticated request. This protects the data in Supabase's Postgres itself. It does not protect it from norc's own servers, so it is not client-side or end-to-end encryption. Machine names, schedules, and run status are stored as-is, protected by row-level security scoped to your account. If your cron commands themselves contain secrets, treat norc's database the way you'd treat any other place those commands are readable, including your own crontab today.

Environment variables work the same way. Values are encrypted server-side (AES-GCM) with your account's own key before storage. This is server-side encryption, not end-to-end or zero-knowledge: norc's servers can decrypt a value, which they must do to deliver it to your machines. After you save a value norc never shows it again, in the web vault, desktop or mobile app; to change it you enter it again. Values go only to your own paired machines, and each machine receives only the variables bound to its own jobs. Each machine keeps its last cached values, in a user-only file on that machine, until it next syncs, so an archive or rotation reaches a machine at its next sync. The cache file, ~/.config/norc/env, is removed when you unpair or sign out on that machine, and when a revoked machine next contacts norc. Each managed job's scheduler line names the variables bound to it (names only, never values), so a job whose variables cannot be fetched and are not in that file fails with a recorded error instead of running without them, also on a machine that is offline, has never synced, or had its file removed. A binding changed in another app reaches the line within seconds while the desktop app is running, and within five minutes on a host running norc bridge; until then a run that cannot reach norc checks the names already on the line plus the cached bindings. A line written by an older version names no variables until one of the two rewrites it, and a host that runs neither does not pick up binding changes made elsewhere. A line that names no variables runs without ones it cannot find, as does a job on a machine that cannot run the bundled agent. A machine that is never online again keeps its file, so delete it by hand on hardware you retire. Deleting a variable is permanent and needs a fresh sign-in; archiving keeps the value, so you can restore it.

norc is not end-to-end encrypted. If that's a requirement for your threat model, don't put anything in a scheduled command you wouldn't want stored server-side.

Where your data lives, and who touches it

Supabase hosts the database, auth, and realtime relay infrastructure. Stripe processes billing, and norc never sees or stores your card number. Vercel hosts norc.app and runs the vault's web server. Cloudflare routes our email, Resend sends account emails, Statsig serves feature flags, Slack receives requests you send from the app, and Google provides analytics (on norc.app and in the vault unless you opt out). If you use AI Studio with your own key, your prompts go to the AI provider you chose (e.g. OpenAI, Anthropic), under that provider's terms, not norc's. No ad networks, no data brokers. The Privacy Policy lists every service and what each one receives.

Your account, job, and machine data is hosted on Supabase infrastructure inside the EU (eu-west-3, Paris), with authentication in eu-west-1, Ireland. That stored data doesn't leave the EU by default. The other services above receive the data the Privacy Policy describes for each, and some of them process it outside the EU. Being EU-hosted means norc's processing of that data falls under the GDPR; we haven't published a Data Processing Agreement or completed a full compliance audit yet, so if either is a hard requirement for your organization, email hello@norc.app before you rely on it.

Self-hosted mode

Not available today. norc's cloud (Supabase-backed relay, auth, and sync) is the only way to run it. If self-hosting the relay is a blocker for you, tell us at hello@norc.app. It's not built, and we'd rather know it's needed than guess.

Open source

The norc apps, relay and vault are private today, not open source, so there's no public repo to audit them. One part is public: norc-mcp, the MCP server, is MIT licensed at github.com/norcapp/norc-mcp. It holds no secrets and only forwards your API key to the vault, and you can read exactly what it sends.

The mechanisms on this page (managed-line tagging, capability signing, the consent gate) describe what the private code does. For those, you have to take our word for it rather than read it yourself.

Questions

Email hello@norc.app with anything this page doesn't answer.