---
title: "Main 27 and the Main mark"
description: "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."
section: "concepts"
status: "Planned for 0.4"
spec: "main27-baseline"
canonical: "https://mainsdk.dev/docs/concepts/main27"
updated: "2026-10-28"
---

# 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: Planned for 0.4 · Canonical: https://mainsdk.dev/docs/concepts/main27 · Updated: 2026-10-28

**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.

```text
$ 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 upgrade` arrives 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](https://mainsdk.dev/docs/concepts/the-check#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.

```jsonc title="/.well-known/mainsdk.json"
{
  "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:

```text
$ 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   none
```

If 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](https://mainsdk.dev/docs/interfaces/auth) shows its level.

## Next

- [The check](https://mainsdk.dev/docs/concepts/the-check)
- [Check codes](https://mainsdk.dev/docs/reference/check-codes)
- [Security model](https://mainsdk.dev/docs/concepts/security-model)
