Skip to content

Commit

Permalink
Add authentication that supports usernames and passwords
Browse files Browse the repository at this point in the history
This commit adds `ask` mode authentication that allows node operators
to configure Bacalhau to ask the user for arbitrary information to be
used as a credential.

This method can be used to implement basic usernames and passwords,
shared secrets, security questions and even 2FA.

The associated policy additionally returns a JSON Schema to show what
information is required. The CLI uses the schema to ask the user for
the right information. In the future, the Web UI will do this as well.
  • Loading branch information
simonwo committed Jan 25, 2024
1 parent 2dffc8d commit 84014b9
Show file tree
Hide file tree
Showing 20 changed files with 607 additions and 18 deletions.
2 changes: 1 addition & 1 deletion apps/job-info-consumer/consumer/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ require (
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.26.0 // indirect
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.19.0 // indirect
Expand Down
2 changes: 1 addition & 1 deletion apps/job-info-consumer/consumer/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1183,7 +1183,7 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
Expand Down
77 changes: 77 additions & 0 deletions cmd/util/auth/ask.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package auth

import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"os"

"github.com/santhosh-tekuri/jsonschema/v5"
"github.com/spf13/cobra"
"golang.org/x/term"
)

// Returns a responder that responds to authentication requirements of type
// `authn.MethodTypeAsk`. Reads the JSON Schema returned by the `ask` endpoint
// and uses it to ask appropriate questions to the user on their terminal, and
// then returns their response as serialized JSON.
func askResponder(cmd *cobra.Command) responder {
return func(request *json.RawMessage) ([]byte, error) {
compiler := jsonschema.NewCompiler()
compiler.ExtractAnnotations = true

if err := compiler.AddResource("", bytes.NewReader(*request)); err != nil {
return nil, err
}

schema, err := compiler.Compile("")
if err != nil {
return nil, err
}

response := make(map[string]any, len(schema.Properties))
for _, name := range schema.Required {
subschema := schema.Properties[name]

if len(subschema.Types) < 1 {
return nil, fmt.Errorf("invalid schema: property %q has no type", name)
}

typ := subschema.Types[0]
if typ == "object" {
return nil, fmt.Errorf("invalid schema: property %q has non-scalar type", name)
}

fmt.Fprintf(cmd.ErrOrStderr(), "%s: ", name)

var input []byte
var err error

// If the property is marked as write only, assume it is a sensitive
// value and make sure we don't display it in the terminal
if subschema.WriteOnly {
input, err = term.ReadPassword(int(os.Stdin.Fd()))
fmt.Fprintln(cmd.ErrOrStderr())
} else {
reader := bufio.NewScanner(cmd.InOrStdin())
if reader.Scan() {
input = reader.Bytes()
}
err = reader.Err()
}

if err != nil {
return nil, err
}
response[name] = string(input)
}

respBytes, err := json.Marshal(response)
if err != nil {
return nil, err
}

return respBytes, schema.Validate(response)
}
}
9 changes: 5 additions & 4 deletions cmd/util/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ import (

type responder = func(request *json.RawMessage) (response []byte, err error)

var supportedMethods map[authn.MethodType]responder = map[authn.MethodType]responder{
authn.MethodTypeChallenge: challenge.Respond,
}

func RunAuthenticationFlow(cmd *cobra.Command) (string, error) {
supportedMethods := map[authn.MethodType]responder{
authn.MethodTypeChallenge: challenge.Respond,
authn.MethodTypeAsk: askResponder(cmd),
}

client := util.GetAPIClientV2(cmd.Context())
methods, err := client.Auth().Methods(&apimodels.ListAuthnMethodsRequest{})
if err != nil {
Expand Down
19 changes: 19 additions & 0 deletions docs/docs/dev/auth_flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,25 @@ return to the endpoint.
}
```

### `ask` authentication

This method requires the user to manually input some information. This method
can be used to implement username and password authentication, shared secret
authentication, and even 2FA or security question auth.

The required information is represented by a JSON Schema in the object itself.
The implementation should parse the JSON Schema and ask the user questions to
populate an object that is valid by it.

```json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://bacalhau.org/auth/ask",
"type": "object",
"$ref": "https://json-schema.org/draft/2020-12/schema",
}
```

## 2. Run the authn flow and submit the result for an access token

The user agent decides which authentication method to use (e.g. by asking the
Expand Down
19 changes: 19 additions & 0 deletions docs/docs/running-node/auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,22 @@ include acceptable client IDs, found by running `bacalhau id`.

Once the node is restarted, only keys in the allowed list will be able to access
any API.

## Username and password access

Users can authenticate using a username and password instead of specifying a
private key for access. Again, this just requires installation of an appropriate
policy.

curl -sL https://raw.githubusercontent.com/bacalhau-project/bacalhau/main/pkg/authn/ask/ask_ns_password.rego -o ~/.bacalhau/ask_ns_password.rego
bacalhau config set Node.Auth.Methods.Password.Type ask
bacalhau config set Node.Auth.Methods.Password.PolicyPath ~/.bacalhau/ask_ns_password.rego

Passwords are not stored in plaintext and are salted. The downloaded policy
expects password hashes and salts generated by `scrypt`. To generate a salted
password, the helper script in `pkg/authn/ask/gen_password` can be used:

cd pkg/authn/ask/gen_password && go run .

This will ask for a password and generate a salt and hash to authenticate with
it. Add the encoded username, salt and hash into the `ask_ns_password.rego`.
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/ricochet2200/go-disk-usage/du v0.0.0-20210707232629-ac9918953285
github.com/rs/zerolog v1.31.0
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.16.0
Expand All @@ -82,7 +83,7 @@ require (
go.uber.org/mock v0.4.0
go.uber.org/multierr v1.11.0
go.uber.org/zap v1.26.0
golang.org/x/crypto v0.17.0
golang.org/x/crypto v0.18.0
golang.org/x/exp v0.0.0-20230321023759-10a507213a29
gopkg.in/alessio/shellescape.v1 v1.0.0-20170105083845-52074bc9df61
k8s.io/apimachinery v0.29.0
Expand Down Expand Up @@ -373,7 +374,7 @@ require (
golang.org/x/oauth2 v0.13.0 // indirect
golang.org/x/sync v0.6.0
golang.org/x/sys v0.16.0 // indirect
golang.org/x/term v0.16.0 // indirect
golang.org/x/term v0.16.0
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0
golang.org/x/tools v0.16.1 // indirect
Expand Down
14 changes: 13 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ github.com/BTBurke/k8sresource v1.2.0 h1:yIwuKJj4cQQVyWF5hGNhXmZNZ3VLLVH1jyGfL0a
github.com/BTBurke/k8sresource v1.2.0/go.mod h1:3Sa2yHvNmOvwzP/WU8joqU4ZbBGUzToZPR9MbaDt38g=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
Expand All @@ -72,6 +73,8 @@ github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8
github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg=
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
Expand All @@ -88,6 +91,7 @@ github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5
github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
Expand Down Expand Up @@ -188,6 +192,7 @@ github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk=
github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
github.com/cheggaaa/pb v1.0.29 h1:FckUN5ngEk2LpvuG0fw1GEFx6LtyY2pWI/Z2QgCnEYo=
github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuPxX30=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
Expand Down Expand Up @@ -261,6 +266,8 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/dylibso/observe-sdk/go v0.0.0-20231201014635-141351c24659 h1:RGgHymaENttkVRf0YEzly0Cr2q8xB56WuDEsn8oFXHE=
github.com/dylibso/observe-sdk/go v0.0.0-20231201014635-141351c24659/go.mod h1:7h4vx/+0cUjKN2f+ynM4tcC8kIjJqP6W2cLcn7buXl4=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs=
github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4=
github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs=
Expand Down Expand Up @@ -587,6 +594,7 @@ github.com/ipfs/go-graphsync v0.14.4/go.mod h1:yT0AfjFgicOoWdAlUJ96tQ5AkuGI4r1ta
github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM=
github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE=
github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ=
github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk=
github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8=
github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8=
github.com/ipfs/go-ipfs-cmds v0.9.0 h1:K0VcXg1l1k6aY6sHnoxYcyimyJQbcV1ueXuWgThmK9Q=
Expand Down Expand Up @@ -1054,6 +1062,7 @@ github.com/ricochet2200/go-disk-usage/du v0.0.0-20210707232629-ac9918953285/go.m
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
Expand All @@ -1069,6 +1078,8 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA=
github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
Expand Down Expand Up @@ -1341,8 +1352,9 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
Expand Down
3 changes: 1 addition & 2 deletions ops/aws/canary/lambda/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -304,14 +304,13 @@ require (
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.26.0 // indirect
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/oauth2 v0.13.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/term v0.16.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.16.1 // indirect
Expand Down
2 changes: 1 addition & 1 deletion ops/aws/canary/lambda/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1176,7 +1176,7 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
Expand Down
34 changes: 34 additions & 0 deletions pkg/authn/ask/ask_ns_example.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package bacalhau.authn

import rego.v1

schema := {
"type": "object",
"properties": {"magic": {"type": "string"}},
"required": ["magic"],
}

token := t if {
input.magic == "open sesame"

t := io.jwt.encode_sign(
{
"typ": "JWT",
"alg": "RS256",
},
{
"iss": input.nodeId,
"sub": "aladdin",
"aud": [input.nodeId],
"iat": now,
"exp": one_month,
"ns": {
# Read-only access to all namespaces
"*": read_only,
# Writable access to own namespace
"genie": full_access,
},
},
input.signingKey,
)
}
67 changes: 67 additions & 0 deletions pkg/authn/ask/ask_ns_password.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package bacalhau.authn

import rego.v1

# Implements a policy where clients that supply a valid username and password
# are permitted access. Anonymous users are not permitted.
#
# Modify the `userlist` to control what users are permitted access.
# Modify the `ns` key of the token to control what namespaces they can access.

schema := {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"username": {"type": "string"},
"password": {"type": "string", "writeOnly": true},
},
"required": ["username", "password"],
}

now := time.now_ns() / 1000

one_month := time.add_date(time.now_ns(), 0, 1, 0) / 1000

# userlist should be a map of usernames to scrypt-hashed passwords and salts. in
# a simple live setup they can be hard coded here as a map, and then apply
# appropriate file permissions to this policy.
userlist := {
# "username": ["hash", "salt"]
}

valid_user := input.ask.username if {
input.ask.username in userlist

hash := userlist[input.ask.username][0]
salt := userlist[input.ask.username][1]
hash == scrypt(input.ask.password, salt)
}

token := io.jwt.encode_sign(
{
"typ": "JWT",
"alg": "RS256",
},
{
"iss": input.nodeId,
"sub": valid_user,
"aud": [input.nodeId],
"iat": now,
"exp": one_month,
"ns": {
# Read-only access to all namespaces
"*": read_only,
# Writable access to own namespace
valid_user: full_access,
},
},
input.signingKey,
)

namespace_read := 1
namespace_write := 2
namespace_download := 4
namespace_cancel := 8

read_only := bits.and(namespace_read, namespace_download)
full_access := bits.and(bits.and(namespace_write, namespace_cancel), read_only)
Loading

0 comments on commit 84014b9

Please sign in to comment.