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


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:

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

2.1 Query Strings

Query strings are PERMITTED but SHOULD be limited to:

Query strings MUST NOT be used for:

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:

4.2 Permitted Syntax

All standard CommonMark elements:

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
`` No JavaScript
`` Embedded third-party content
`` Data collection
`` 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:

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:

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:

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:


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:


9. Security Considerations

Remaining vectors:


10. Future Considerations

Items explicitly deferred for future versions:


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:


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.