HTTP/Minimal#

Version: 0.1.0-draft
Status: Proposal

Abstract#

HTTP/Minimal is a constrained version of HTTP designed for serving human-readable documents without tracking, scripting, or behavioral manipulation. It is not a new protocol - it is a voluntary restriction on how HTTP is used, enforceable by clients and verifiable by automated tools.

Goals#

  1. Radical simplicity. A document is text and links. Maybe images.
  2. Privacy by architecture. No cookies, no auth headers, no state.
  3. Zero JavaScript. Not "minimal scripts" - none.
  4. Works today. Any static file server can serve compliant content.
  5. Human-writable source. Content is authored in Markdown, not markup soup.

Non-Goals#

  • Replacing HTTP for applications, APIs, or dynamic content
  • Defining a new transport protocol
  • Competing with Gemini (this is HTTP; use Gemini if you want Gemini)

1. Transport Requirements#

1.1 TLS Required#

All HTTP/Minimal content MUST be served over HTTPS (TLS 1.2+, TLS 1.3 RECOMMENDED).

Plain HTTP requests SHOULD receive a 301 redirect to the HTTPS equivalent and nothing else.

1.2 HTTP Version#

HTTP/1.1, HTTP/2, and HTTP/3 are all acceptable. Servers SHOULD support HTTP/2 at minimum.


2. Request Constraints#

Compliant clients MUST NOT send the following headers:

Header Reason
Cookie State tracking
Authorization Implies authenticated content
DNT Unnecessary - tracking is minimized by design
X-Requested-With AJAX patterns not applicable
Any X- header Custom headers are a slippery slope

Compliant clients MUST use only these methods:

  • GET - Retrieve a document
  • HEAD - Check if a document exists or has changed

All other methods (POST, PUT, DELETE, etc.) are non-compliant.

2.1 Query Strings#

Query strings are PERMITTED but SHOULD be limited to:

  • Pagination (?page=2)

Query strings MUST NOT be used for:

  • Session tracking
  • User identification
  • Analytics parameters (utm_*, fbclid, etc.)

Compliant servers SHOULD ignore or strip unrecognized query parameters.


3. Response Constraints#

3.1 Forbidden Response Headers#

Compliant servers MUST NOT send:

Header Reason
Set-Cookie State tracking
WWW-Authenticate Implies auth-gated content
Content-Security-Policy Implies executable content to policy
X-Frame-Options Embedding restrictions suggest app behavior
Refresh Client-side redirects enable tracking

3.2 Permitted Response Headers#

Servers SHOULD send:

Header Purpose
Content-Type Required (text/markdown; charset=utf-8)
Content-Length Required for HTTP/1.1
Last-Modified Caching
ETag Caching
Cache-Control Caching (SHOULD be generous; max-age=3600 or higher)
Link Discovery (see Section 6)

3.3 Status Codes#

Compliant servers SHOULD limit responses to:

Code Meaning
200 OK
301 Moved Permanently
304 Not Modified
400 Bad Request
404 Not Found
410 Gone (content deliberately removed)
500 Server Error

Codes 302, 303, and 307 are NOT RECOMMENDED as they enable tracking redirects.


4. Content Format#

HTTP/Minimal uses Markdown as its content format, served with Content-Type text/markdown; charset=utf-8.

4.1 Markdown Variant#

HTTP/Minimal uses CommonMark as the base specification, with the following extensions PERMITTED:

  • Tables - GitHub Flavored Markdown (GFM) pipe tables
  • Strikethrough - ~~text~~
  • Autolinks - GFM automatic URL linking
  • Footnotes - [^1] reference-style footnotes

4.2 Permitted Syntax#

All standard CommonMark elements:

  • Headings (#, ##, etc.)
  • Paragraphs
  • Emphasis (*italic*, **bold**)
  • Links ([text](url) or [text][ref])
  • Images (![alt](url))
  • Blockquotes (>)
  • Code spans (`code`)
  • Code blocks (fenced or indented)
  • Lists (ordered and unordered)
  • Horizontal rules (---)
  • Hard line breaks

4.3 Forbidden Syntax#

The following MUST NOT appear in HTTP/Minimal documents:

Syntax Reason
Raw HTML blocks Enables script injection, tracking pixels, forms
Raw HTML inline Same
<script> No JavaScript
<iframe> Embedded third-party content
<form> Data collection
<img> with tracking URLs Use Markdown image syntax with compliant URLs

Clients MUST strip or ignore any raw HTML encountered in Markdown source.

4.4 Image Requirements#

Images referenced via ![alt](url) syntax:

  • MUST include alt text (the [alt] portion MUST NOT be empty)
  • SHOULD be same-origin or from trusted, non-tracking sources
  • MUST NOT be 1x1 tracking pixels

Links are unrestricted in destination -HTTP/Minimal documents MAY link to any URL.

Clients MAY warn users when following links to non-compliant origins.

4.5.1 URL Fragments#

URL fragments (#section-name) are supported and SHOULD work as follows:

  • When rendering Markdown to HTML, headings SHOULD receive auto-generated id attributes based on their text (lowercase, spaces replaced with hyphens)
  • Clients receiving text/markdown SHOULD scroll to the heading matching the fragment
  • Fragment matching SHOULD be case-insensitive

For example, ## My Section would be reachable via #my-section.

4.6 Metadata#

Document metadata SHOULD be provided via a YAML front matter block:

---
title: My Document
author: Jane Doe
date: 2025-12-27
lang: en
---

# My Document

Content begins here.

Recognized front matter fields:

Field Required Description
title RECOMMENDED Document title
author No Author name or identifier
date No Publication date (ISO 8601)
lang No Language code (BCP 47)
license No Content license (SPDX identifier or URL)

Clients SHOULD use title for window/tab titles and lang for text rendering.


5. Client Rendering#

5.1 Dedicated Clients#

HTTP/Minimal clients SHOULD:

  1. Parse Markdown and render to styled, readable output
  2. Apply a legible default stylesheet (user-configurable)
  3. Strip any raw HTML before rendering
  4. Display images inline with alt text fallback
  5. Make links clearly navigable

5.2 Browser Rendering#

Standard browsers receiving text/markdown will typically display raw source. Options for browser compatibility:

Option A: Server-side rendering

Servers MAY content-negotiate and serve pre-rendered HTML to browsers:

  • Request with Accept: text/markdown → serve Markdown
  • Request with Accept: text/html → serve HTML rendering

The HTML rendering MUST be a direct transformation of the Markdown source with no additions (no scripts, no tracking, no analytics).

Option B: Client-side rendering via browser extension

Browser extensions may render text/markdown responses directly.

Option C: Raw display

Markdown is human-readable as source. No rendering required.

5.3 Suggested Default Styles#

Clients SHOULD apply sensible typographic defaults:

  • Readable font (system serif or sans-serif)
  • Comfortable line length (45-75 characters)
  • Adequate line height (1.4-1.6)
  • Responsive viewport handling
  • Respect user preferences (dark mode, font size)

6. Discovery and Verification#

6.1 Well-Known Endpoint#

Compliant servers SHOULD serve a policy document at:

/.well-known/http-minimal

This document is a JSON object:

{
  "http_minimal": "0.1",
  "compliant": true,
  "scope": "/",
  "contact": "mailto:admin@example.com",
  "validator": "https://example.com/validation-report.json"
}
Field Required Description
http_minimal Yes Spec version
compliant Yes Self-attestation
scope No Path prefix this policy applies to (default: entire origin)
contact No Maintainer contact
validator No URL to a third-party validation report

Responses MAY include:

Link: </.well-known/http-minimal>; rel="profile"

6.3 Compliance Badge (Optional)#

Documents MAY include a compliance indicator:

---
[HTTP/Minimal Compliant](/.well-known/http-minimal)

7. Example Document#

---
title: Welcome to HTTP/Minimal
author: Jane Doe
date: 2025-12-27
lang: en
---

# Welcome to HTTP/Minimal

This is a document served over **HTTP/Minimal** - a constrained version of
HTTPS for human-readable content without tracking, scripts, or manipulation.

## What is this?

HTTP/Minimal is not a new protocol. It's a voluntary restriction on how 
HTTP is used:

- HTTPS only, no exceptions
- No cookies or authentication headers
- No JavaScript, ever
- Content is Markdown, not HTML

## Why Markdown?

Markdown is:

1. Human-readable as source
2. Human-writable without tooling
3. Transparent - tracking pixels are visible in source and enforceable by clients
4. Universally supported

## Learn More

Read the full [specification](/spec) or view the 
[source for this page](/source/index.md).

---

*[HTTP/Minimal Compliant](/.well-known/http-minimal)*

8. Relationship to Other Specifications#

Gemini Protocol#

HTTP/Minimal shares philosophical goals with Gemini (simplicity, anti-tracking, anti-JavaScript) but differs in approach:

Aspect Gemini HTTP/Minimal
Transport New protocol (gemini://) HTTPS
Content format text/gemini text/markdown
Browser support Requires dedicated client Works with extensions or server-side rendering
Port 1965 443

Gemtext vs Markdown#

Gemini's text/gemini format is simpler than Markdown (one link per line, no inline formatting). HTTP/Minimal accepts the tradeoff of a slightly more complex format for broader tooling support.

Semantic Web / Microformats#

HTTP/Minimal Markdown documents can include semantic meaning via:

  • Structured YAML front matter
  • Consistent heading hierarchies
  • Machine-parseable date/author metadata

9. Security Considerations#

  • No cookies eliminates CSRF and session hijacking vectors
  • No JavaScript eliminates XSS entirely
  • No forms eliminates CSRF for data submission
  • No raw HTML prevents injection attacks
  • HTTPS required ensures transport security

Remaining vectors:

  • Malicious links - users may still be linked to harmful external sites
  • Image-based tracking - external images can still leak requests; clients MAY block third-party images
  • Cache timing - sophisticated attackers may infer browsing history via cache timing; out of scope

10. Future Considerations#

Items explicitly deferred for future versions:

  • Signed content - integration with Signed HTTP Exchanges or content-addressed storage
  • Content addressing - integration with IPFS, AT Protocol, or content-hash URLs
  • Client certificates - Gemini-style TOFU identity without cookies
  • Extended metadata - richer front matter schemas (JSON-LD, etc.)
  • Media embedding - whether/how to handle audio and video

Appendix A: Validator Pseudocode#

def validate_response(response):
    errors = []
    
    # Check forbidden response headers
    forbidden = ['set-cookie', 'www-authenticate', 'refresh']
    for header in forbidden:
        if header in response.headers:
            errors.append(f"Forbidden header: {header}")
    
    # Check content type
    content_type = response.headers.get('content-type', '')
    if not content_type.startswith('text/markdown'):
        errors.append("Content-Type must be text/markdown")
    
    # Parse Markdown
    doc = parse_markdown(response.body)
    
    # Check for raw HTML
    if contains_raw_html(doc):
        errors.append("Raw HTML is forbidden")
    
    # Check images have alt text
    for image in doc.images:
        if not image.alt:
            errors.append(f"Image missing alt text: {image.url}")
    
    return errors

Appendix B: Content-Type Registration#

This specification uses text/markdown as defined in RFC 7763.

Recommended Content-Type header:

Content-Type: text/markdown; charset=utf-8; variant=CommonMark

Appendix C: Migration Checklist#

For existing sites adopting HTTP/Minimal:

  • Enable HTTPS if not already
  • Convert content to Markdown (or add Markdown alongside HTML)
  • Configure server to serve .md files as text/markdown
  • Remove all analytics (Google Analytics, Plausible, etc.)
  • Remove comment systems or link to external discussion
  • Ensure all images have alt text
  • Ensure no raw HTML in Markdown source
  • Add /.well-known/http-minimal endpoint
  • Run validator against all documents
  • Optional: implement content negotiation for HTML clients

Appendix D: Server Configuration Examples#

Nginx#

location ~ \.md$ {
    types { text/markdown md; }
    charset utf-8;
    add_header Link '</.well-known/http-minimal>; rel="profile"';
    
    # Remove forbidden headers (shouldn't exist, but defensive)
    proxy_hide_header Set-Cookie;
    proxy_hide_header WWW-Authenticate;
}

Caddy#

@markdown path *.md
header @markdown Content-Type "text/markdown; charset=utf-8"
header @markdown Link "</.well-known/http-minimal>; rel=\"profile\""
header @markdown -Set-Cookie

Static file server (Go)#

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    if r.Method != "GET" && r.Method != "HEAD" {
        http.Error(w, "Method not allowed", 405)
        return
    }
    
    if strings.HasSuffix(r.URL.Path, ".md") {
        w.Header().Set("Content-Type", "text/markdown; charset=utf-8")
        w.Header().Set("Link", "</.well-known/http-minimal>; rel=\"profile\"")
    }
    
    http.FileServer(http.Dir("./public")).ServeHTTP(w, r)
})

Acknowledgments#

This specification draws inspiration from:


License#

This specification is released under CC0 1.0 Universal - no rights reserved. Use it, fork it, improve it.