FTN8.1: FutoIn Security Concept - Stateless Authentication
Version: 0.4DV
Date: 2018-05-17
Copyright: 2014-2018 FutoIn Project (http://futoin.org)
Authors: Andrey Galkin

CHANGES

1. Intro

This sub-specification of FTN8 covers the simplest Stateless Authentication for Clients and Services.

The ultimate goal is to authenticate user based on local user ID and pre-shared secret (password) without automatic Secret renewal.

The following methods are defined:

  1. Clear Text
  2. Simple MAC based on Secret

2. Concept

This scheme does no support foreign users.

The following "sec" field definition refer to FTN3 request message "Security-defined extension" element.

The Secret used in requests must be separate from all other secrets to prevent exposure of those. It's assumed that there is a unique User Secret per Service as Service should be able to retrieve the Secret from AuthService for caching purposes.

2.1. Clear text method

Clear text directly corresponds to HTTP Basic Authentication.

Main parameters are:

However, this sub-spec allows using "login:password" pairs outside of HTTP requests headers.

Use of this method is discouraged and should be limited to not important functionality accessed through SecureChannel.

2.1.1. Clear text request "sec" field structured format

Schema: futoin-sec-credentials

{
    "title" : "FutoIn 'sec' field - Credentials",
    "type" : "object",
    "additionalProperties" : false,
    "required" : [ "user" ],
    "properties" : {
        "user" : {
            "type" : "string",
            "description" : "Unique user identification"
        },
        "secret" : {
            "type" : "string",
            "description" : "Any type of secret, typically password"
        }
    }
}

2.1.2. Clear text request "sec" field format as string

String representation format is "{user}:{secret}" without brackets. Such format is size efficient for transmission.

2.1.3. Clear text response "sec" field

The field must not be present as there is no point for that.

2.1.4. Clear text security level

SafeOps security level must be assigned.

2.2. Simple MAC method

Please refer to main FTN8 spec for details of generation and validation.

Main parameters are:

The method has serious advantages over clear text method:

There are still some problems:

However, it's still relatively simple to implement with meaningful advantages.

2.2.1. Simple MAC request "sec" field structured format

Schema: futoin-sec-simple-mac

{
    "title" : "FutoIn 'sec' field - Simple MAC",
    "type" : "object",
    "additionalProperties" : false,
    "required" : [ "user", "algo", "sig" ],
    "properties" : {
        "user" : {
            "type" : "string",
            "description" : "Unique user identification"
        },
        "algo" : {
            "type" : "string",
            "description" : "MAC algo name as defined in FTN8"
        },
        "sig" : {
            "type" : "string",
            "description" : "Base64 encoded MAC"
        }
    }
}

2.2.2. Simple MAC request "sec" field string format

Preferred for message size reduction.

    "-smac:{user}:{algo}:{sig}"

2.2.3. Simple MAC response "sec" field

Response must be authenticated by the same Secret and the same hash algorithm as used for request signing. Only signature has to be sent.

2.2.4. Simple MAC security level

PrivilegedOps security level must be assigned.

2.3. Events

2.3.1. New secret set events

2.4. Backward compatibility to historical "#basicauth" interface

For many years, a temporary solution similar to this spec was used. The major difference was to use classical usernames instead of local user IDs.

To allow smooth transition, there should be optional implementation-defined way to map legacy usernames to local user IDs.

3. Interface

3.1. Message authentication

The interface is used only to process stateless authentication requests. It is designed the way when MAC secret is always kept inside AuthService to minimize risk of exposure.

{
    "iface" : "futoin.auth.stateless",
    "version" : "{ver}",
    "ftn3rev" : "1.9",
    "imports" : [
        "futoin.ping:1.0",
        "futoin.auth.types:{ver}"
    ],
    "types" : {
        "ClearSecField" : {
            "type" : "map",
            "fields" : {
                "user" : "LocalUserID",
                "secret" : "Password"
            }
        },
        "MACSecField" : {
            "type" : "map",
            "fields" : {
                "user" : "LocalUserID",
                "algo" : "MACAlgo",
                "sig" : "MACValue"
            }
        }
    },
    "funcs" : {
        "checkClear" : {
            "params" : {
                "sec" : "ClearSecField",
                "source" : "ClientFingerprints"
            },
            "result" : "AuthInfo",
            "throws" : [
                "SecurityError"
            ],
            "seclvl" : "SafeOps"
        },
        "checkMAC" : {
            "params" : {
                "base" : "MACBase",
                "sec" : "MACSecField",
                "source" : "ClientFingerprints"
            },
            "result" : "AuthInfo",
            "throws" : [
                "SecurityError"
            ],
            "seclvl" : "PrivilegedOps"
        },
        "genMAC" : {
            "params" : {
                "base" : "MACBase",
                "reqsec" : "MACSecField"
            },
            "result" : "MACValue",
            "throws" : [
                "SecurityError"
            ],
            "seclvl" : "PrivilegedOps"
        },
        "getMACSecret" : {
            "params" : {
                "user" : "LocalUserID"
            },
            "result" : "MACKey",
            "throws" : [
                "UnknownUser",
                "NotSet"
            ],
            "desc" : "For internal caching purposes",
            "seclvl" : "PrivilegedOps"
        }
    },
    "requires" : [
        "SecureChannel",
        "MessageSignature",
        "BinaryData"
    ]
}

3.2. Management

This one is complementary to "futoin.auth.manage" iface.

{
    "iface" : "futoin.auth.stateless.manage",
    "version" : "{ver}",
    "ftn3rev" : "1.9",
    "imports" : [
        "futoin.ping:1.0",
        "futoin.auth.types:{ver}"
    ],
    "funcs" : {
        "genNewSecret" : {
            "params" : {
                "user" : "LocalUserID",
                "service" : "LocalUserID",
                "for_mac" : "boolean"
            },
            "result" : "StatelessSecret",
            "throws" : [
                "UnknownUser"
            ],
            "seclvl" : "System"
        },
        "getSecret" : {
            "params" : {
                "user" : "LocalUserID",
                "service" : "LocalUserID",
                "for_mac" : "boolean"
            },
            "result" : "StatelessSecret",
            "throws" : [
                "UnknownUser",
                "NotSet"
            ],
            "seclvl" : "System"
        },
        "removeSecret" : {
            "params" : {
                "user" : "LocalUserID",
                "service" : "LocalUserID",
                "for_mac" : "boolean"
            },
            "result" : "boolean",
            "throws" : [
                "UnknownUser"
            ],
            "seclvl" : "System"
        }
    },
    "requires" : [
        "SecureChannel",
        "MessageSignature"
    ]
}

=END OF SPEC=