REP-002 - Import/Export RestAuth data
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". |
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:
services
users
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
- ↑ Ertl, M., et al., "RestAuth", Specification
- ↑ 2.0 2.1 Crockford, D., "The application/json Media Type for JavaScript Object Notation (JSON)", RFC 4627, July 2006.
- ↑ 3.0 3.1 Klyne, G., Newman, C., "Date and Time on the Internet: Timestamps", RFC 3339, July 2002
- ↑ Resnick, P., "Internet Message Format", RFC 5322, October 2008
- ↑ Berners-Lee, T., et al., "Uniform Resource Identifier (URI): Generic Syntax", RFC 3986, January 2005
- ↑ Newman, et al., "Salted Challenge Response Authentication Mechanism (SCRAM) SASL and GSS-API Mechanisms", RFC 5802, July 2012.
- ↑ Drepper, U., "Unix crypt with SHA-256/512", Official specification, September 2009
- ↑ Cite error: Invalid
<ref>
tag; no text was provided for refs namedjson schema draft
Informative references
- ↑ PHPass documentation
- ↑ bcrypt specification
- ↑ DES-Crypt reference implementation
- ↑ MD5-Crypt reference implementation
- ↑ json-schema.org - The home of JSON Schema
Authorship information
- 2014, 2015, Mathias Ertl, mati@restauth.net