Main 27 and the Main mark
Main 27 is the named, versioned minimum every MainSDK app meets. The Main mark proves a release holds it. Interfaces ship as stable, beta or experimental.
Status Status is where the work is: Planned (in a milestone, not started), Building (tickets in progress), Preview (usable, may change), then the stability it ships at.
Stability The promise an interface ships with.
- Stable Follows semantic versioning; breaking changes need a new major, 12 months of overlap and a codemod.
- Beta Usable in production; may change before it becomes stable.
- Experimental May change or go away; needs an explicit opt-in in main.yaml.
Main 27 is the baseline every MainSDK app meets: modern methods only, named by generation for the year it serves, the way TLS 1.2 gave the web a minimum everyone could trust. It ships in autumn 2026 and leads through 2027. mainsdk check enforces it with stable rule IDs.
What Main 27 requires
| Area | MainSDK default | Not allowed | Rule prefix |
|---|---|---|---|
| Network | TLS 1.3 everywhere public, mTLS between your own services, HSTS | Plain HTTP, old TLS, weak ciphers | MAIN-NET |
| Sign-in | Passkeys, OIDC and OAuth 2.1 with PKCE, SAML or OIDC SSO, WhatsApp one-time codes | Home-made password storage, implicit flow, long-lived tokens | MAIN-AUTH |
| Sessions | Short-lived HttpOnly SameSite cookies, rotating refresh tokens | Tokens in local storage | MAIN-SESSION |
| Secrets | Vault or cloud KMS, workload identity | Keys in code, committed .env files | MAIN-SECRET |
| Database | Typed queries, row-level security, encryption at rest, field encryption for personal data | SQL from strings, shared admin credentials | MAIN-DATA |
| APIs | Schema-validated input, rate limits, CORS allowlist, signed webhooks | Unvalidated input, open CORS | MAIN-API |
| Logging | Structured OpenTelemetry logs, personal data hidden, append-only audit log | Secrets or personal data in logs, editable audit logs | MAIN-LOG |
| Crypto | Modern authenticated encryption, Argon2id for passwords | MD5, SHA-1, DES, home-made crypto | MAIN-CRYPTO |
| Supply chain | Pinned, provenance-checked packages, SBOM per release | Unpinned or unverified packages | MAIN-SUPPLY |
| Releases | Signed builds and updates | Unsigned binaries or updates | MAIN-RELEASE |
mTLS needs control of both ends, so it covers your own services. Third-party APIs must offer TLS 1.2 or later; anything weaker is flagged.
Main 27 is also a bill of contracts: it lists the exact version of every interface contract it includes, so "Main 27" means the same thing to every app, driver and auditor.
$ npx mainsdk check --explain-baseline
generation main27 point 27.0
rules MAIN-NET-*, MAIN-AUTH-*, MAIN-SESSION-*, MAIN-SECRET-*, MAIN-DATA-*, MAIN-API-*,
MAIN-LOG-*, MAIN-CRYPTO-*, MAIN-SUPPLY-*, MAIN-RELEASE-*
contracts email 1.4 · policy 1 · telemetry 1 · …Generations and point updates
- Point updates (27.1, 27.2) only add checks during the year. They never remove a guarantee.
- Overlap: the previous generation stays valid for 12 months after the next one ships.
- Upgrades: Main 28 follows in autumn 2027, and
mainsdk upgradearrives with it to move an app to the next generation with codemods. - Support: each baseline has a long-term support line of at least 24 months.
The Main mark
A release that holds every guarantee carries the Main mark. Your app version stays your own.
| Who reads it | Form |
|---|---|
| People | "Pinecart 2.4.1 · Main 27" |
| Machines | 2.4.1+main27, semver build metadata, which never changes version ordering |
| State | When |
|---|---|
| Main 27 | Every guarantee holds |
| Main 27 · 1 exception (amber) | An exception is open (see exceptions) |
| No mark | The generation has lapsed |
The mark is backed by a signed record at /.well-known/mainsdk.json, also referenced from the SBOM and SLSA provenance. It records the generation, open exceptions, contract versions, and which agents and models wrote the changes that passed the gates.
{
"schema": "mainsdk-mark@1",
"project": "prj_01JC8Q4W7ZK3M5N8P2R6T9V0XY", "app": "Pinecart", "version": "2.4.1",
"mark": "2.4.1+main27", "generation": "main27", "point": "27.0",
"state": "pass",
"exceptions": [],
"contracts": { "email": "1.4", "policy": "1", "telemetry": "1" },
"agents": [{ "agent": "claude-code", "model": "anthropic/claude-*", "changes": 37 }],
"build": { "commit": "4f2c1e9", "provenance": "slsa:…", "sbom": "cyclonedx:…" },
"signature": { "type": "sigstore", "bundle": "…" }
}Anyone can verify any running app:
$ npx mainsdk info https://orders.pinecart.dev
Pinecart 2.4.1 · Main 27 prj_01JC8Q… (2.4.1+main27)
Signed Sigstore · SLSA provenance · built 24 Oct 2026 from pinecart/pinecart@4f2c1e9
Interfaces auth (github) · ai (bedrock) · db (postgres) · files (getqr)
Exceptions noneIf one byte of the record changes, verification fails with MAIN-INFO-0002 signature does not verify.
The Main mark is an open specification (mainsdk-mark@1) with a JSON Schema. Any tool can verify it, and any SDK that passes the guarantees can earn it.
Still open: who signs the mark in phase 1. The proposal is developer Sigstore keyless signing in phase 1 and MainSDK countersigning from phase 2. The trust badge and the public trust page come with the launch report.
Standards mapping
Each rule carries its mapping as data: OWASP ASVS 5.0 chapter, OWASP Top 10:2025 category, SOC 2 criteria and ISO/IEC 27001:2022 Annex A. A secret in the browser bundle, for example, maps to ASVS V13, Top 10 A02, SOC 2 CC6.1 and ISO 27001 5.17. The launch report prints the mapping per control. Mapping helps you pass a review; it is not a certification.
Stability levels
Every interface declares a level in its contract.
| Level | What it promises |
|---|---|
stable | The contract follows semantic versioning; breaking changes need a new major, 12 months of overlap and a codemod |
beta | Usable in production; may change before it becomes stable |
experimental | May change or go away; needs an explicit opt-in in main.yaml (the key is not decided yet) |
The phase 1 stable core is config, policy, access, auth, db, secrets, log, email, pay, files, webhooks and jobs. Other interfaces stay beta until they have two drivers, a passing conformance suite and three production users. mainsdk check lists every beta or experimental interface your app uses. Each interface page shows its level.
Next
Was this page helpful?