Skip to content

Instantly share code, notes, and snippets.

@bsawyer
Last active April 28, 2020 19:15
Show Gist options
  • Save bsawyer/b8fa71c990e22b6474b278ea3c1ad254 to your computer and use it in GitHub Desktop.
Save bsawyer/b8fa71c990e22b6474b278ea3c1ad254 to your computer and use it in GitHub Desktop.

This is a very informal RFC draft

tl;dr I'm trying to write a protocol and URL scheme, one that uses existing protocols to make it easier to find web resources. This is not intended as a replacement for any existing protocols

What problem are you trying to address?

Being able to access a web resource by its intended name.

I'll use Datadog (no affiliation) as an example.

Their domain is https://www.datadoghq.com/ while the intended name is Datadog.

How do you find their site today?

If I wanted to go to Datadog's website today I would enter datadog, the name I'm familiar with, into a search engine.

How would you like to find their site?

  • What if I could just type @datadog into my client, be it a Browser, CLI, etc. and have it resolve to their website?
  • What if I could write an email to @datadog@support or even enter @datadog@support@email and have it open my email client with their email address?
  • What if I could make requests to their API by addressing @datadog@api without having to worry about 301's, or API version upgrades?

How would you do that?

An optionally stateless, decentralized protocol that can be implemented by agents with the purpose of resolving web resources by their intended names. A protocol that works with existing IP's, maximizing interoperability.

How is this different then...

DNS lookups?

...

Editing your host file?

...

Gnunet's GNS or (insert name system here)?

...

The Spec

Handle Syntax

The handle establishes a new URI scheme. It is a sequence of components, each defined as any number of characters, preceded by the @ character.

@[schemaurl]@[schemahash]@[schemaencoded]@[name]

While each component is optional at least one handle must follow the @ character.

schemaurl

This is a URL that returns a schema file. e.g. https://www.datadoghq.com/schema.json

schemahash

This is a short or long SHA256 hash of a Base64-encoded ASCII string of the target schema file. It is for clients to resolve cached versions if they exist.

schemaencoded

This is a Base64-encoded ASCII string of the target schema file.

name

The handle name is any additional handle segment to be resolved using the template syntax.

Every handle segment is optional. It would be possible to access @https://www.datadoghq.com/schema.json@s9fa9da9@datadag, @s9fa9da9@datadag, or @datadog, they would all resolve to the same output.

Template Syntax

  • A scopes template can be a literal string value.

  • It also supports interpolated values from previously resolved scopes or dynamic values e.g. #{[handle]}.

It cannot reference a parent or child scope handle in its template.

  • It can also extend another scope by setting the value to another scopes handle and optionally replacing the extended scopes template e.g. [handle]:[template].

It cannot extend a child scope

Examples

Given the schema:

{
  "version": "1.0.0",
  "scopes": {
    "@datadog": "datadoghq.com",
    "@datadog@eu": "@datadog:datadoghq.eu",
    "@datadog@api": "api.#{@datadog}/api/#{@datadog@api}",
    "@datadog@https": "https://#{@datadog}/#{@datadog@https}"
  }
}

The following would resolve to

@datadog@eu@api -> api.datadoghq.eu/api/

Dynamic values

@datadog@https@about -> https://datadoghq.com/about

Agent Resolve

Below defines the protocol for resolving a handles component parts

Schema

The following is a pseudo code example of how an agent resolves a handles schema file

segments = handle.split('@')

if isCached(segments, cache)
  return getCache(segments, cache)

else if isEncoded(segments[0])
  schema = decode(segments[0])
else if isUrl(segments[0])
  schema = fetch(segments[0])

if schema
  hash = hashSchema(schema)
  cacheSchema(segments[0], hash, schema, cache)
  return getCache(segments, cache)

else
  return :(

Scope

Given a handle and its associated schema file, the following is pseudo code of how a agent resolves a handles scope

segments = handle.split('@')
...

Output

Given a handle and its associated scope, the following is pseudo code of how a agent resolves a handles output

segments = handle.split('@')
...

Schema Format

{
  version: 1,
  scopes: {
    handle: template
  }
}

Scope Format

This is the same as the full schema but only the scopes included in a particular handle

{
  version: 1,
  scopes: {
    handle: template
  }
}

Output Format

The output format is defined by the target scopes template. The output does not have to be an absolute URI.

TODO

  • come up with a name for the protocol
  • write a rest service that implements the protocol
  • write a web client that optionally assigns itself as a protocol handler
  • write a CLI client that optionally assigns itself as a protocol handler
  • write a redirect service that provides automatic URL redirection

Example REST API

The rest api will be responsible for proxying schema files, resolving a scope, and parsing and formatting a handle to a URL. It will act as an agent implementing the protocol.

GET /api/v1/resolve/${handle}

This endpoint will return a response payload with the following format

{
  ok: true,
  schema: {
    version,
    scopes
  },
  scope: {
    handle: template
  },
  output: string
}

If there is an error the response format is

{
  ok: false,
  error: message
}

FAQ

How are scopes with the same name resolved?

The unique identifier will be the first component i.e. the schema file URL. Once the address is cached by either the client or the service it will no longer need to be included in the full handle. If there are multiple scopes with the same name cached, the agent will proceed with a search and return a list of matching handles and their associated scopes.

How does this protocol interoperate with existing protocols like DNS?

This protocol is not meant to be a replacement for DNS. The protocol would not override any DNS records. A handle lookup may or may not return a URI.

What is the security model?

Similar to a site owner validation process where the vetting agent validates that the response body of an HTTP request to the domain matches some criteria e.g. Google Analytics site validation.

@bsawyer
Copy link
Author

bsawyer commented Apr 28, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment