REP-002 - Import/Export RestAuth data

From RestAuth
Jump to: navigation, search

This document specifies REP-002 - Import/Export RestAuth data, a data format that contains data from or for a RestAuth<ref name="restauth" group="n"/> service. The format is a subset of JSON<ref name="rfc 4627" group="n"/>. Files matching the specification might be used to export data from a service and import them into a RestAuth server or to move existing data to a different RestAuth server implementation.

Introduction

The file format uses JSON<ref name="rfc 4627" group="n" /> to encode the data. JSON is the primary data interchange format used by RestAuth, both encoders and decoders are widely available in almost any programming language. A JSON-Schema is provided below.

Notation

The following notation standards apply to this document:

  • Literal values look like this: services
  • Example values look like this: examples.com
  • The terms "JSON object", "JSON string" and "JSON array" reference the respective data types in the JSON specification.

Basic structure

At the topmost level, an REP-002 file must contain a JSON object containing up to three key/value pairs, identified by these keys:

  • services for importing credentials.
  • users for importing users.
  • groups for importing groups.

All keys are optional, but the file must of course contain at least one key to be useful.

Services

The value for the services key must be itself a JSON object where each key represents the name of the service and the corresponding value is again a JSON object describing the service. This object may contain any of these two key/value pairs:

key value
password See Passwords.
hosts A JSON array of JSON strings containing one or more IP-Addresses that this service can connect from.

Note: Depending on the scenario, cleartext passwords might actually be preferable if available, e.g. so an importing service can use a hashing algorithm of its own choice.

This is an example specifying four services:

{
    "services": {
        "example.at": {},
        "example.org": {
            "hosts": [
                "127.0.0.1",
                "::1"
            ]
        },
        "example.net": {
            "password": {
                "hash": "$apr1$fd7YiwYk$P.jfn.Q64kh6cpmTpAxy30",
                "algorithm": "apr_md5_crypt"
            }
        },
        "example.com": {
            "password": {
                "hash": "plaintext-password",
                "algorithm": "plain"
            },
            "hosts": [
                "127.0.0.1",
                "::1"
            ]
        }
    }
}

In this example, only example.com is actually usable (from localhost). The other services may still be usable if the service already exists. In the case of example.org, for example, the two named hostnames would be added to an existing service with the same name. The example.net service provides a password as hashed by Apache's "htpasswd" utility.

Users

The value for users must itself be a JSON object where each key represents the name of the user and the corresponding value is a JSON object describing the user. The object can contain two key/value pairs, both are optional:

key value
password See Passwords.
properties A JSON object containing any user properties.


All values of the properties object must be JSON strings. All strings are free-form, except:

Property Format
date joined A JSON string formatted according to RFC 3339<ref name="rfc 3339" group="n" />, section 5.6, e.g. "2015-01-11T17:54:12.143553+01:00".
last login A JSON string formatted according to RFC 3339<ref name="rfc 3339" group="n" />, section 5.6, e.g. "2015-01-11T17:54:12.143553+01:00".
email A valid E-Mail address formatted according to RFC 5322<ref name="rfc 5322" group="n" />, section 3.4.1, e.g. "user@example.com".
url A valid URI according to RFC 3986<ref name="rfc 3986" group="n" />, e.g. "https://example.com/~username".

An example specifying three users:

{
    "users": {
        "bareuser": {},
        "onlypassword": {
            "password": {
                "hash": "this user only has a password, no properties.",
                "algorithm": "plain"
            }
        },
        "mati": {
            "password": {
                "hash": "plaintext-password",
                "algorithm": "plain"
            },
            "properties": {
                "email": "mati@example.com",
                "last login": "2015-01-11T17:54:12.143553+01:00",
                "full name": "Mathias Ertl",
                "date joined": "2015-01-01T17:54:12.143553+01:00"
            }
        },
        "full example": {
            "password": {
                "hash": "$apr1$fd7YiwYk$P.jfn.Q64kh6cpmTpAxy30",
                "algorithm": "apr_md5_crypt"
            },
            "properties": {
                "email": "mati@fsinf.at",
                "last login": "2015-01-11T16:54:12.143553+01:00",
                "full name": "foo foo",
                "date joined": "2015-01-01T16:54:12.143553+01:00"
            }
        }
    }
}

Groups

The value for groups must itself be a JSON object where each key represents the name of a group and the corresponding value is a JSON object describing it. The object can contain three key/value pairs, all are optional:

key value
users A JSON array of JSON strings, each naming a member. If empty or omitted, the group has no members.
service A JSON string naming the service. If omitted, the group has no service.
subgroups A JSON object with two key/value pairs. The mandatory name key names the group, the optional service field names the service of the named group.


The following example shows two groups for the service example.com. The users group is a subgroup of the admin group, so each user in the admins group is also a member of the users group:

{
    "groups": {
        "admins": {
            "users": [
                "administrator"
            ],
            "service": "example.com"
        },
        "users": {
            "users": [
                "normal-user",
                "normal-user 2"
            ],
            "service": "example.com",
            "subgroups": [
                {
                    "name": "admins",
                    "service": "example.com"
                }
            ]
        }
    }
}

Passwords

Both services and users can contain a password field. Such a field is a JSON object with two key/value pairs:

  • algorithm is a JSON string naming the algorithm used.
  • hash is a JSON string containing the hash as stored by the exporting application.

A number of hashes are defined here:

Algorithm Description
plain A plain text password.
unknown A hash not named here. An import script may try to guess the algorithm.
apr_md5_crypt Hashes as created by Apache's "htpasswd" utility.
phpass Hashes as created by phpass<ref name="phpass" />.
bcrypt Hashes as created by bcrypt<ref name="bcrypt" />.
scram SCRAM<ref name="rfc 5802" group="n" /> hashes.
des_crypt, md5_crypt, sha256_crypt, sha512_crypt The password hashing schemes used by various flavours of Unix and Linux. See des_crypt<ref name="des_crypt" />, md5_crypt<ref name="md5_crypt" /> and sha256_crypt<ref name="sha256_crypt" group="n" /> for reference.

Considerations for import scripts

Import scripts primarily need to handle that importing data might fail halfway through. As such, an import script should take care to:

  • Validate that the data actually makes sense (e.g. groups don't reference subgroups that are neither present nor would be created by the file).
  • Make sure that importing data is handled as a single transaction, meaning that either all data or no data at all is imported.

Order of import

An import script must import data in precisely the given order:

  1. services
  2. users
  3. groups

If any of the keys are not present, they can be safely skipped. The import order is important because groups might reference users and services created by the document.

Groups defined within the document might name subgroups defined and created in the same document. This usually means that scripts have to create every named group first and only then create any subgroup relations.

JSON-Schema

A JSON-schema (see the official website<ref name="json-schema" /> or the IETF draft<ref name="json schema draft" group="n" />) can always be downloaded from here:

 https://restauth.net/rep-002.json

References

Normative references

<references group="n"> <ref name="rfc 4627">Crockford, D., "The application/json Media Type for JavaScript Object Notation (JSON)", RFC 4627, July 2006.</ref> <ref name="restauth">Ertl, M., et al., "RestAuth", Specification</ref> <ref name="rfc 3339">Klyne, G., Newman, C., "Date and Time on the Internet: Timestamps", RFC 3339, July 2002</ref> <ref name="rfc 5322">Resnick, P., "Internet Message Format", RFC 5322, October 2008</ref> <ref name="rfc 3986">Berners-Lee, T., et al., "Uniform Resource Identifier (URI): Generic Syntax", RFC 3986, January 2005</ref> <ref name="rfc 5802">Newman, et al., "Salted Challenge Response Authentication Mechanism (SCRAM) SASL and GSS-API Mechanisms", RFC 5802, July 2012.</ref> <ref name="sha256_crypt">Drepper, U., "Unix crypt with SHA-256/512", Official specification, September 2009</ref> <ref name="json schema draft">Galiegue, F., Zyp, K., Court, G., "JSON Schema: core definitions and terminology", JSON Schema Draft 4, January 2013 </references>

Informative references

<references> <ref name="phpass">PHPass documentation</ref> <ref name="bcrypt">bcrypt specification</ref> <ref name="des_crypt">DES-Crypt reference implementation</ref> <ref name="md5_crypt">MD5-Crypt reference implementation</ref> <ref name="json-schema">json-schema.org - The home of JSON Schema</ref> </references>

Authorship information

  • 2014, 2015, Mathias Ertl, mati@restauth.net