farmfa

command module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 13, 2022 License: Apache-2.0 Imports: 6 Imported by: 0

README

= {product}
Giorgio Azzinnaro <giorgio@azzinna.ro>
:toc:
:includedir: docs/_include
:product: farMFA
:repo: borgoat/farmfa

image:https://img.shields.io/github/license/{repo}?color=blue&style=flat-square[License, link=LICENSE]
image:https://goreportcard.com/badge/github.com/{repo}[Go Report Card, link=https://goreportcard.com/report/github.com/{repo}]
image:https://pkg.go.dev/badge/github.com/{repo}[PkgGoDev, link=https://pkg.go.dev/github.com/{repo}]


== Concept

Multi Factor Authentication is usually implemented by using the TOTP standard <<RFC6238>> from OATH.

* A secret key is shared upon activation and stored by the user (usually in an app such as Authenticator)
and by the authentication server.
* Upon login, the user, after providing the credentials, will input a One-Time Password.
This password is generated applying the TOTP algorithm to the secret key and to the current time.
* The server will generate the same password, and if they match, the user will be able to go through.
The secret key is never shared again by the user or the server.

The generated One-Time Password, as the name suggests, may only be used once
(or more precisely, within a timeframe of around 30 seconds to 90 seconds, depending on the server implementation).

{product} comes into play in shared environments where access to certain accounts
should be restricted to very special occasions
(for example, access to the root user of an AWS account,
especially the root user of the management account of an AWS Organization).
In this context, we can secure the access in such a way that, after the credentials to the account are retrieved,
the second level of authorisation must come from multiple individuals.
First of all, we apply _Shamir's Secret Sharing_ scheme <<2>> to the original TOTP secret key,
so that at least 3 of 5 holders are needed to reconstruct it.
Additionally, the TOTP secret key is only ever reconstructed in {product}'s server memory,
meaning no single player has ever to risk accessing and accidentally leaking/persisting it.
After having reconstructed the secret, {product} will then generate one or more OTPs for the dealer,
until the session expires.

== Getting started

{product} is a client-server application.
Some operations are stateless (the creation of the shares) and may even be executed client-side,
while managing authentication sessions (joining shares, generating TOTP) relies on the server memory.
When using an optional persistence layer, all data is encrypted at rest,
and may only be decrypted once the applicant provides a decryption key.

=== Split TOTP secret and share

To split a TOTP secret and generate <<Toc,Tocs>>, you need the Age public keys of players.

You can generate Age keys via https://github.com/FiloSottile/age#readme[age-keygen]:

[source,shell]
----
$ age-keygen -o your_own_key.txt
----

All <<player,players>> run the same command, and share their public key with the <<dealer>>.

Now the dealer may start the process. Usually, they also provide their own public key and keep one Toc.

[source,shell]
----
$ farmfa dealer \
  --totp-secret HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ \
  -p player_1=age174uc3d7qzaulmm75huxazcaynq5et4s9gdr7ajnau204lqny7asq9ens77 \
  -p player_2=age1pa8m7l4sguj84c5v8qu9gr3mydnmhd8lf633ln2udlp5699uvp2sm2mpzd \
  -p player_3=age1qegd5t5ajlqzewruz38srlrz05w7xgzq4nn2n5gky872up553v8sl64j3j
----

This command will return encrypted Tocs, 1 per player.

Assuming the dealer is also player #1, they can now decrypt their own Toc to verify its content.

[source,shell]
----
$ age -i your_own_key.txt --decrypt
[paste the encrypted Toc - Ctrl+D]

{
    "group_id": "7GCUCI2Y",
    "group_size": 3,
    "group_threshold": 3,
    "note":"",
    "share":"C2iCgb3pRfxPJw2a7od8p4ShkhrDWAm/Dt6ioQNAVFPZ",
    "toc_id":"5oaAUX9b6aBE"
}
----


=== Generate a TOTP

When a user wants to log in they can start a <<session>>. We'll now refer to them as <<applicant>>.

[source,shell]
.Applicant
----
$ http --body POST localhost:8080/sessions toc_zero:='{"group_id":"J7UHQPZK","group_size":5,"group_threshold":2,"share":"5Ovpu-PKEeYXx5ebiQhzU_AT0Z79POf8GGkskDp3its=urkBkVXr-pYjIvTt1ch2YJILCScAoRquLoX_VBxxps4=","toc_id":"TFW52GAK"}'
{
    "complete": false,
    "created_at": "2021-02-24T18:05:53.507396809+01:00",
    "id": "V5K6QD4XUFLRGCZH",
    "kek": "MIotBtYOWrXnQCj6o9rSNIkNeRfIPhNLjEdQtJDDemPRJcKUbme+iq5K2Hc6Ypil6Loi/K9rnN/YrJiKDT/tPi8kFq2WuAY8zl8=",
    "tek": "age1cl5ndmdsq09vs09awlpt8nd4cdu6fpl33lpyyuv75syknqalkpdszwnwyc",
    "toc_group_id": "J7UHQPZK",
    "tocs_in_group": 5,
    "tocs_provided": 1,
    "tocs_threshold": 2
}

----

The applicant now shares the _Toc Encryption Key (TEK)_ with team members who hold other <<Toc,Tocs>> of the same group.
Those team members who want to authorise the applicant will become the session's <<constituent,constituents>>.

Constituents must encrypt and armor their Toc with TEK (using https://age-encryption.org/[Age]).

[source,shell]
.Constituent
----
$ export ENCTOC=$(echo '{"group_id":"J7UHQPZK","group_size":5,"group_threshold":2,"share":"zxRrozuUaCMgn_u6ajZStlV7RKwhp0keT9aQoXAEruI=nfx2CPJfKiFM32zLmtxHjV94OlZOgBevV1Whrx-lslU=","toc_id":"K5FSSJSV"}' | age -r age1cl5ndmdsq09vs09awlpt8nd4cdu6fpl33lpyyuv75syknqalkpdszwnwyc -a)
----

Constituents now share the encrypted Toc with the <<oracle>>, and associate it with the existing session.

[source,shell]
.Constituent
----
$ http POST localhost:8080/sessions/V5K6QD4XUFLRGCZH/tocs encrypted_toc="$ENCTOC"
HTTP/1.1 200 OK
----

Once enough Tocs have been provided to the oracle, the applicant may now query the oracle.
The applicant must provide the session's KEK to authorise the oracle to decrypt the Tocs, and generate the <<TOTP>>.

[source,shell]
.Constituent
----
$ http --body POST localhost:8080/sessions/V5K6QD4XUFLRGCZH/totp kek="MIotBtYOWrXnQCj6o9rSNIkNeRfIPhNLjEdQtJDDemPRJcKUbme+iq5K2Hc6Ypil6Loi/K9rnN/YrJiKDT/tPi8kFq2WuAY8zl8="
{
    "totp": "824588"
}

----


include::{includedir}/bibliography.adoc[]

include::{includedir}/glossary.adoc[]

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
Package api provides primitives to interact with the openapi HTTP API.
Package api provides primitives to interact with the openapi HTTP API.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL