REP-002 - Import/Export RestAuth data

From RestAuth
Jump to navigation Jump to search

This document specifies REP-002 - Import/Export RestAuth data, a data format that contains data from or for a RestAuth[n 1] service. The format is a subset of JSON[n 2]. 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[n 2] 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[n 3], section 5.6, e.g. "2015-01-11T17:54:12.143553+01:00".
last login A JSON string formatted according to RFC 3339[n 3], section 5.6, e.g. "2015-01-11T17:54:12.143553+01:00".
email A valid E-Mail address formatted according to RFC 5322[n 4], section 3.4.1, e.g. "user@example.com".
url A valid URI according to RFC 3986[n 5], 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[1].
bcrypt Hashes as created by bcrypt[2].
scram SCRAM[n 6] hashes.
des_crypt, md5_crypt, sha256_crypt, sha512_crypt The password hashing schemes used by various flavours of Unix and Linux. See des_crypt[3], md5_crypt[4] and sha256_crypt[n 7] 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[5] or the IETF draft[n 8]) can always be downloaded from here:

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

References

Normative references

  1. Ertl, M., et al., "RestAuth", Specification
  2. 2.0 2.1 Crockford, D., "The application/json Media Type for JavaScript Object Notation (JSON)", RFC 4627, July 2006.
  3. 3.0 3.1 Klyne, G., Newman, C., "Date and Time on the Internet: Timestamps", RFC 3339, July 2002
  4. Resnick, P., "Internet Message Format", RFC 5322, October 2008
  5. Berners-Lee, T., et al., "Uniform Resource Identifier (URI): Generic Syntax", RFC 3986, January 2005
  6. Newman, et al., "Salted Challenge Response Authentication Mechanism (SCRAM) SASL and GSS-API Mechanisms", RFC 5802, July 2012.
  7. Drepper, U., "Unix crypt with SHA-256/512", Official specification, September 2009
  8. Cite error: Invalid <ref> tag; no text was provided for refs named json schema draft

Informative references

Authorship information

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