Internet-Draft HashBack October 2026
Godfrey Expires 26 April 2027 [Page]
Workgroup:
Network Working Group
Published:
Intended Status:
Informational
Expires:
Author:
W. Godfrey
billpg industries

HashBack: Server-to-Server Authentication by Published Hash

Abstract

HashBack is a two-step authentication exchange carried over HTTPS/TLS that allows one HTTP server to authenticate another, without either party holding a long-term shared secret, bearer token, or private key. A prover demonstrates its identity by publishing a short cryptographic hash on a website it controls; the verifier of a request fetches that hash over a second, independent HTTPS connection and compares it against a value it calculates itself. If the two values match, the verifier is reassured that the prover is who it claims to be. This document describes the HashBack exchange, the format of the Authorization header it defines, and the security considerations that apply to implementations.

Note to the RFC Editor

This note is to be removed before publishing as an RFC.

This document uses "NNNN" as a placeholder for its own RFC number in the Version string "RFC_NNNN" (see the Version member in Section 5.1, and the example WWW-Authenticate header that follows the discovery description). Please replace every occurrence of NNNN with the number assigned to this document, then remove this note.

The example Authorization header field in Section 5.1 and the expected verification hash in Section 6 are both computed from the example JSON object, which currently carries the Version value "BILLPG_DRAFT_4.2". If that example is changed to show "RFC_NNNN" instead, those two values must be regenerated rather than text-substituted - replacing NNNN alone would leave them wrong, since they are derived from the exact bytes of the JSON. The authors will supply the regenerated values. (The Fixed Salt does not depend on the Version value and is unaffected.)

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on 26 April 2027.

▲

Table of Contents

1. Introduction

A server that calls out to another server over the Internet typically needs some way to prove its identity: an API key, a bearer token, a shared secret, or a private key backing a client TLS certificate. Whichever form it takes, that credential has to be generated, distributed to the calling service, stored securely at both ends, and eventually rotated - all before the two services can exchange a single authenticated request.

HashBack removes the need for that long-term credential entirely. Instead, it relies on a property both parties already have if they are communicating over HTTPS at all: each side runs a TLS-secured web server that the other side can reach. HashBack uses this in a manner similar to a phone call placed to a trusted number and then immediately hung up so the other side can call back: the prover tells the verifier "I am the operator of this URL - call me back there to check", and publishes a value at that URL for the verifier to retrieve.

This is deliberately similar in spirit to the challenge exchange used by the Automatic Certificate Management Environment (ACME) [RFC8555], which validates control of a domain name by asking the requester to publish a token there ahead of a certificate being issued. HashBack applies the same "prove control of a URL" idea to general-purpose API authentication, and reduces the exchange to two HTTP transactions instead of three.

This document is an early, individual Internet-Draft. It has not been adopted by any IETF working group. It is published to invite review and comment ahead of a future submission for standardization.

2. Terminology and Notation

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

This document additionally uses the following terms:

Prover:
The party sending the HTTP request being authenticated.
Verifier:
The party receiving and authenticating the HTTP request.
Unus:
A 128-bit cryptographic-quality random value, encoded in Base64, included in every request to make its verification hash unpredictable. Equivalent in purpose to a cryptographic nonce. The name is the Latin word for "one" or "single".
Verify URL:
An HTTPS URL, under the Prover's control, where the Prover publishes the verification hash for a given request.
Verification hash:
The Base64-encoded, salted SHA-256 hash of a request's JSON object, as described in Section 6.
Fixed Salt:
A 32-byte value, fixed by this document and not secret, prepended to a request's bytes before hashing. See Section 6.

3. Protocol Overview

In outline, the Prover builds a JSON object describing the request it is about to make, including the URL where it will publish that object's hash. It sends this object, Base64-encoded, in the HTTP Authorization header of its request. Before or immediately after sending that request, it publishes the object's verification hash at the declared URL.

On receiving the request, the Verifier parses the Authorization header, applies its own policy checks (see Section 7), and then makes a separate HTTPS GET request to the Verify URL to retrieve the published hash. The Verifier computes the same hash itself from the bytes it received and compares the two values. If they match, the Verifier has confirmed that whoever controls the Verify URL endorses this specific request, and processes it accordingly.

Two independent HTTPS connections are used: the original request, and the Verifier's GET request to the Verify URL. Because TLS secures both connections, and because the published value is a hash of the specific request rather than a fixed shared secret, this exchange requires no pre-agreed credential beyond the Verifier knowing which range of Verify URLs belong to which Prover (see Section 4).

4. Prerequisite: Declaring a Verify URL Range

Before this exchange can take place, the Verifier MUST have a way to map an incoming Verify URL to a specific, known Prover identity. Exactly how this mapping is established and stored is outside the scope of this document (it might be an entry in a configuration file, a row in a database populated through a self-service web portal, or a value baked into deployment configuration), but the range of URLs accepted for any one Prover MUST be narrow enough that no other party could plausibly publish content there.

A single fixed URL, or a URL varying only in a query string parameter or a restricted path segment, is appropriate. A URL prefix that could allow the Prover's other users to publish arbitrary content (for example, a path serving user comments or a public wiki) is not, because it would let an unrelated party impersonate the Prover by publishing a hash of their own choosing under that same prefix.

Examples of acceptable and unacceptable declarations:

Table 1: Verify URL range examples
Pattern Acceptable? Reason
https://example.com/hashback?id=* Yes Single fixed path, varying only in a query parameter
https://example.com/hashback/*.txt Yes Single restricted folder, no further subfolders
http://example.com/hashback/* No Not protected by TLS
https://example.com/* No Too broad; covers content the Prover does not control
https://example.com/blog/* No May allow third-party comments

5. The Authorization Header

The Prover authenticates its request using the HTTP Authorization request header field, using the auth-scheme token HashBack:

Authorization = "HashBack" 1*SP token68

where token68 is as defined by Section 11.3 of [RFC9110]. The token68 value MUST be the standard Base64 encoding (Section 4 of [RFC4648], including padding, and without line breaks) of a JSON object, encoded as UTF-8, described below. (Line breaks shown in examples in this document are for presentation only and are not part of the header value.)

5.1. JSON Object Properties

The JSON object MUST be a JSON object, as defined by [RFC8259], containing exactly the following members. All values are strings unless stated otherwise. All members are REQUIRED.

Version:
A string identifying the version of this exchange in use. This revision of this exchange is identified by the string "BILLPG_DRAFT_4.2", the label it already carries in the reference implementation and in the informal, pre-IETF drafts that preceded this document. A future revision of this document, once adopted as an IETF work item, is expected to define a new version string of the form "RFC_NNNN", where NNNN is the number ultimately assigned to that RFC.
Host:
The full domain name of the Verifier being called in this request. Because intermediaries such as load balancers and content delivery networks can rewrite the HTTP Host header, this property carries an authoritative copy included in the hashed material, so there is no ambiguity about which name the Prover intended. The Verifier MUST reject any request whose Host property does not match one of its own recognized names, including generic names such as "localhost" that belong to no specific service. See Section 10.2.
Now:
The current UTC time, expressed as an integer number of seconds since the start of 1970 (a Unix timestamp), as defined by "Seconds Since the Epoch" in Section 4.16 of [POSIX.1-2017]. Provers and Verifiers MUST use an integer type wider than 32 bits when generating or reading this value, so that this mechanism continues to function beyond the year 2038. The Verifier SHOULD reject a request if this value is too far from its own clock; this document does not mandate a specific threshold, leaving that to the Verifier's own configuration.
Unus:
128 bits of cryptographic-quality randomness, Base64-encoded including any trailing "=" padding. Every other property of this JSON object is potentially predictable to an attacker; the security of this exchange depends on this value, and only this value, being unpredictable (see Section 10.3). A Prover MUST NOT reuse a Unus value across requests. A Verifier SHOULD reject any request reusing a Unus value it has already seen within its configured Now tolerance window.
Verify:
An https:// URL, belonging to the Prover, from which the Verifier can retrieve the verification hash with an HTTP GET request. This URL MUST fall within a range the Verifier has already associated with a specific Prover identity, per Section 4.

If either the Host or Verify property would otherwise contain a non-ASCII internationalized domain name, that name MUST be normalized and represented either as literal UTF-8 or using JSON's \u escape notation, and MUST NOT use the ToASCII ("xn--") form.

For example, the following JSON object:

{
    "Version": "BILLPG_DRAFT_4.2",
    "Host": "server.example",
    "Now": 529297200,
    "Unus": "Rpgt4Fc5nMDq14LOps/hYQ==",
    "Verify": "https://client.example/api/hashback?id=502542886"
}

is Base64-encoded and sent as the following Authorization header field:

Authorization: HashBack
 eyJWZXJzaW9uIjoiQklMTFBHX0RSQUZUXzQuMiIsIkhvc3QiOiJzZXJ2ZXIuZXhhbXBs
 ZSIsIk5vdyI6NTI5Mjk3MjAwLCJVbnVzIjoiUnBndDRGYzVuTURxMTRMT3BzL2hZUT09
 IiwiVmVyaWZ5IjoiaHR0cHM6Ly9jbGllbnQuZXhhbXBsZS9hcGkvaGFzaGJhY2s/aWQ9
 NTAyNTQyODg2In0=

6. Verification Hash Calculation and Publication

Both the Prover and the Verifier compute the verification hash the same way, from the same bytes: the exact UTF-8 byte sequence that was (or will be) Base64-decoded from the Authorization header. The hash MUST be computed as follows:

  1. Concatenate the 32-byte Fixed Salt below with the UTF-8 bytes of the JSON object, salt first.
  2. Compute the SHA-256 digest ([RFC6234]) of the concatenated bytes.
  3. Base64-encode the 32-byte digest, including any trailing "=" padding.

The Fixed Salt is the following 32 bytes:

48,106,239,61,141,188,122,117,
71,242,89,164,154,89,44,47,
20,42,34,245,250,230,139,30,
56,240,40,168,35,184,92,252

equivalently, in Base64: MGrvPY28enVH8lmkmlksLxQqIvX65oseOPAoqCO4XPw=, or in hexadecimal: 306AEF3D8DBC7A7547F259A49A592C2F142A22F5FAE68B1E38F028A823B85CFC.

The Fixed Salt is NOT a secret. Its only purpose is to ensure a HashBack verification hash cannot be confused with, or produced by, an unrelated general-purpose hashing service, since that service would not have prepended this same value. It was generated using PBKDF2 with the following parameters, provided here for transparency and reproducibility rather than as part of the algorithm implementers need to run:

Password:
"HashBack is dedicated to my Treacle."
Salt:
"I love you to the moon and back."
Hash algorithm:
SHA-512
Iterations:
477708
Output:
256 bits

The expected verification hash for the example request in Section 5.1 is /+Zc/xVCVgnnfC69tEybe2TAluOk21ScdystX0/1Ayk=.

Once computed, the Prover MUST publish the verification hash at the Verify URL before, or without excessive delay after, sending the authenticated request, so that it is available by the time the Verifier fetches it. The response to a GET request for the Verify URL MUST:

The Verifier compares the hash it downloads against the hash it computes itself from the bytes it decoded from the Authorization header. If the Verifier cannot retrieve a matching hash - because of a network failure, an unexpected status code, a certificate problem, or a mismatched value - it MUST treat the request as unauthenticated and respond with a suitable HTTP error, with enough detail in the response to help a reasonably experienced developer correct the problem.

7. Verifier Processing

On receiving a request bearing a HashBack Authorization header, the Verifier MUST perform the following checks, in any order, before treating the request as authenticated:

  1. The request arrived over HTTPS, the Authorization header uses the HashBack auth-scheme, and its token68 value Base64-decodes to a well-formed JSON object with all the members listed in Section 5.1.
  2. The Version property is one this Verifier implements.
  3. The Host property is a name this Verifier recognizes as itself (see Section 10.2).
  4. The Now property is within the Verifier's configured tolerance of its own clock.
  5. The Unus property is well-formed and, if replay protection is configured, has not already been seen.
  6. The Verify property is an HTTPS URL the Verifier can map to a specific, known Prover identity, per Section 4.
  7. The verification hash retrieved from the Verify URL matches the hash the Verifier computes itself, per Section 6.

If every check passes, the Verifier treats the request as authenticated as the Prover identity associated with the Verify URL, and proceeds to process the request that carried the header. If any check fails, the Verifier MUST NOT process the request and SHOULD respond with an HTTP 4xx status code.

8. Advertising Support via WWW-Authenticate

A Verifier rejecting an unauthenticated request with a 401 response MAY advertise support for this exchange using a WWW-Authenticate response header field Section 11.6.1 of [RFC9110] whose auth-scheme is HashBack. An optional realm auth-param MAY be present. An optional version auth-param, if present, MUST be a comma-separated list of Version values this Verifier accepts, most preferred first; a Prover SHOULD select a value from this list when building its next request. Absence of the version parameter does not imply that HashBack is unsupported.

HTTP/1.1 401 Unauthorized
WWW-Authenticate: HashBack realm="My_Wonderful_Realm"
 version="RFC_NNNN,BILLPG_DRAFT_4.2,BILLPG_DRAFT_4.1"

A Prover that already knows a Verifier supports HashBack MAY send the Authorization header on its first request, skipping this discovery step.

9. Repeated Requests

Every HashBack exchange requires a fresh JSON object, a freshly published verification hash, and therefore a second HTTPS round trip on the Verifier's side. This is inherently more expensive than reusing a bearer token, and this document intentionally does not define a token format or refresh mechanism to sit on top of it.

Implementations that need to authenticate many requests in succession are RECOMMENDED to run one HashBack exchange and then have the Verifier issue its own short-lived credential - for example, a bearer token or a Set-Cookie response header - that the Prover then presents for subsequent requests until it expires, at which point the HashBack exchange is repeated. The format, lifetime, and transport of that credential is outside the scope of this document.

10. Security Considerations

10.1. Dependency on TLS

This exchange depends entirely on the security properties of TLS for both HTTP transactions. It provides no security of its own against an attacker capable of defeating TLS - such as one holding a certificate improperly issued by a trusted certificate authority - beyond whatever precautions an implementation separately takes, such as maintaining its own restricted set of trusted certificate authorities or pinning certificates for known Provers.

10.2. Relay ("Pass-Along") Attacks

Without the Host property, a Verifier that is itself malicious, or that has been compromised, could take a valid request received from a genuine Prover and forward it unmodified to a third Verifier, which would retrieve the same verification hash and be fooled into believing it was talking directly to the original Prover. Because Host is included in the hashed material, a forwarded request would carry the wrong Host value for the third Verifier, and Section 7 requires that value be rejected. For this reason, a Verifier MUST reject any request whose Host property is not a name it recognizes as its own, including generic names such as "localhost" that could belong to any server.

10.3. Predictability of Request Contents

With the exception of Unus, every property of the JSON object described in Section 5.1 may be entirely predictable to an attacker without weakening this exchange. An attacker who can predict or observe a Verify URL and its published hash still cannot construct a valid request for a different Verifier, because doing so requires finding a JSON object - including a Unus value - that hashes to that same value, which is computationally infeasible against SHA-256. Implementations therefore MUST generate Unus using a cryptographically secure random number generator, and MUST NOT reuse a value.

10.4. Server-Side Request Forgery Considerations

Fetching a URL supplied in an incoming request carries the usual SSRF risks associated with any user-supplied URL fetch. Implementations SHOULD apply the same precautions they would to any other outbound fetch of prover-supplied data: resolving and validating the destination address before connecting, rejecting internal or loopback address ranges unless explicitly intended (for example, during local development), declining to follow redirects (see Section 6), and applying a request timeout.

10.5. Denial of Service Considerations

Because every incoming request with a HashBack header causes the Verifier to make a further outbound HTTPS request, a flood of fabricated Authorization headers could be used to exhaust a Verifier's outbound connection capacity, even though every one of those requests will ultimately fail verification. Implementations SHOULD apply a short connection and response timeout to the Verify URL fetch, and MAY track and rate-limit sources of requests that repeatedly fail verification.

A related concern is a malicious Verify URL that accepts the connection but never completes the response, tying up a connection on the Verifier for as long as it is willing to wait. A short, strictly enforced timeout on the Verify URL fetch mitigates this; the timeout only needs to be long enough for the expected response to arrive under normal network conditions.

11. IANA Considerations

This document requests registration of "HashBack" in the "Hypertext Transfer Protocol (HTTP) Authentication Scheme Registry" defined by Section 16.4 of [RFC9110]:

Table 2: HTTP Authentication Scheme Registration
Field Value
Authentication Scheme Name HashBack
Pointer to specification text This document
Notes (none)

This document defines no new media types, URI schemes, or other IANA registries at this time.

12. Acknowledgements

The author thanks Danny Wilson for feedback and for developing an independent implementation of this exchange; multiple independent implementations are valuable when establishing a new standard. The author also thanks "buzer" of Hacker News for raising the slow-verification-URL denial-of-service concern discussed in Section 10.5.

13. Normative References

[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, , <https://www.rfc-editor.org/info/rfc8174>.
[RFC8259]
Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, , <https://www.rfc-editor.org/info/rfc8259>.
[RFC9110]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Semantics", STD 97, RFC 9110, , <https://www.rfc-editor.org/info/rfc9110>.
[RFC4648]
Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", RFC 4648, , <https://www.rfc-editor.org/info/rfc4648>.
[RFC6234]
Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)", RFC 6234, , <https://www.rfc-editor.org/info/rfc6234>.
[POSIX.1-2017]
IEEE and The Open Group, "The Open Group Base Specifications Issue 7, 2018 edition (IEEE Std 1003.1-2017)", , <https://pubs.opengroup.org/onlinepubs/9699919799/>.

14. Informative References

[RFC8555]
Barnes, R., Hoffman-Andrews, J., McCarney, D., and J. Kasten, "Automatic Certificate Management Environment (ACME)", RFC 8555, , <https://www.rfc-editor.org/info/rfc8555>.

Appendix A. Reference Implementation

A reference implementation in C# ("HashBackCore"), along with a publicly reachable demo service exercising both the Prover and Verifier roles, is maintained alongside the source of this document at https://github.com/billpg/HashBack. Interested implementers are encouraged to test their own implementations against it and to report interoperability issues there.

Author's Address

William Godfrey
billpg industries