Skip to content

Commit 2cf54fe

Browse files
committed
Merge remote-tracking branch 'refs/remotes/origin/main'
2 parents ab73f54 + 16f07d6 commit 2cf54fe

File tree

5 files changed

+168
-5
lines changed

5 files changed

+168
-5
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ you use the published checksums to verify integrity.
3939

4040
## Development Setup
4141

42-
1. Build the plugin for your platform:
42+
1. Build the plugin for your platform (`os/arch`) e.g.:
4343

4444
```sh
4545
$ make darwin/arm64
@@ -131,16 +131,16 @@ When a token is successfully created, the plugin attach a policy that follows th
131131
You must then create a policy with that name in Vault that utilises the metadata stored in the alias. The following policy template will allow access to a KV secret at the path `secret/data/[namespace]/[object]*`:
132132

133133
```hcl
134-
path "secret/data/{{identity.entity.aliases.[auth plugin accessor].metadata.namespace}}/{{identity.entity.aliases.[auth plugin accessor].metadata.object}}*" {
134+
path "secret/data/{{identity.entity.aliases.auth_vault-plugin-auth-ory_e40b77a0.metadata.object}}*" {
135135
capabilities = ["create", "update", "read"]
136136
}
137137
138-
path "secret/metadata/{{identity.entity.aliases.[auth plugin accessor].metadata.namespace}}/{{identity.entity.aliases.[auth plugin accessor].metadata.object}}}*" {
138+
path "secret/metadata/{{identity.entity.aliases.auth_vault-plugin-auth-ory_e40b77a0.metadata.object}}/" {
139139
capabilities = ["list"]
140140
}
141141
```
142142

143-
Being sure to replace `[auth plugin accessor]` with the accessor of the auth plugin found by running `vault auth list`.
143+
Being sure to replace `auth_vault-plugin-auth-ory_e40b77a0` with the accessor of the auth plugin found by running `vault auth list`.
144144

145145
Alternatively, you can find the accessor by running the following command:
146146

auth/ory_auth.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package auth
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/hashicorp/vault/api"
8+
"github.com/pkg/errors"
9+
)
10+
11+
// NewOryAuth creates an OryAuth struct that can be passed into the client.Auth().Login
12+
// method to authenticate with Vault via the Ory auth plugin.
13+
//
14+
// The mount path should be the path that the plugin was mounted at (probably `ory`)
15+
// The namespace, object, and relation should reflect the resource being requested
16+
// The cookie should be the full cookie string, including the name and `=`
17+
// e.g. `ory_kratos_session=MyReallyLongSessionCookieString`
18+
func NewOryAuth(
19+
mountPath, namespace, object, relation, cookie string,
20+
) (*OryAuth, error) {
21+
switch {
22+
case mountPath == "":
23+
return nil, errors.New("no mount path provided")
24+
case namespace == "":
25+
return nil, errors.New("no namespace provided")
26+
case object == "":
27+
return nil, errors.New("no object provided")
28+
case relation == "":
29+
return nil, errors.New("no relation provided")
30+
case cookie == "":
31+
return nil, errors.New("no cookie provided")
32+
}
33+
34+
return &OryAuth{
35+
mountPath: mountPath,
36+
namespace: namespace,
37+
object: object,
38+
relation: relation,
39+
cookie: cookie,
40+
}, nil
41+
}
42+
43+
// OryAuth is a Vault AuthMethod that can communicate to the Ory plugin
44+
type OryAuth struct {
45+
mountPath string
46+
47+
namespace string
48+
object string
49+
relation string
50+
cookie string
51+
}
52+
53+
// Login performs a login request to the Ory Vault auth plugin.
54+
func (a *OryAuth) Login(ctx context.Context, client *api.Client) (*api.Secret, error) {
55+
if ctx == nil {
56+
ctx = context.Background()
57+
}
58+
loginData := map[string]interface{}{
59+
"namespace": a.namespace,
60+
"object": a.object,
61+
"relation": a.relation,
62+
"kratos_session_cookie": a.cookie,
63+
}
64+
path := fmt.Sprintf("auth/%s/login", a.mountPath)
65+
resp, err := client.Logical().WriteWithContext(ctx, path, loginData)
66+
if err != nil {
67+
return nil, errors.Wrap(err, "unable to log in with Ory auth")
68+
}
69+
70+
return resp, nil
71+
}

example/main.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"os"
7+
8+
ory "github.com/comnoco/vault-plugin-auth-ory/auth"
9+
10+
"github.com/hashicorp/vault/api"
11+
"github.com/pkg/errors"
12+
)
13+
14+
func main() {
15+
if err := run(); err != nil {
16+
fmt.Println(err)
17+
os.Exit(0)
18+
}
19+
}
20+
21+
func run() error {
22+
secretName := "top_secret"
23+
mountPath := "ory"
24+
namespace := "secret"
25+
object := "e00de7c2-1ee2-4508-b95c-c3c0d881d0cc"
26+
relation := "viewer"
27+
cookie := "ory_kratos_session=MTY3NzA4MzI4M3xQRTV3RUp2MHdWblNSaWtQcDhKMjdtLXBqSDJ2eGFQTm9NbktFX0dlNWlJaUV4U1hFdmhscVM0ZEIyU3dzMHJROVUxTjk2NkdqM0xoR3dJeXNmNEpFUFhHMC1Rc0hJa0VldEdnazk0OFlfaVpqc0J2Rng3cDNOVHZ5a0xnbDVRWF9haHZjMjMxRk9iQmhJYUVZMUdrZFNSN29NQmVzOGVvWGpBaVNVVk9ReHl0aGtWSlFjZ1FtZldvand2cjVSbndDWEtqVENOVkJJMGVQMHRfYXBoTE0wTXk5SXVDM2UyOFo2TDEtdENxWTRkb01KV2NwLV83bG10WTVEaXhBa0FENy1UOUxrSjE4TU0tfGvmo31B3VG9JarStNbFB7TXOV8dhbvTq1mhZaEI8HEN"
28+
vaultAddr := "https://localhost:8200/"
29+
30+
vaultCfg := api.DefaultConfig()
31+
vaultCfg.Address = vaultAddr
32+
vault, err := api.NewClient(vaultCfg)
33+
if err != nil {
34+
return errors.Wrap(err, "unable to create Vault API Client")
35+
}
36+
37+
auth, err := ory.NewOryAuth(
38+
mountPath,
39+
namespace,
40+
object,
41+
relation,
42+
cookie,
43+
)
44+
if err != nil {
45+
return errors.Wrap(err, "failed to make ory auth method")
46+
}
47+
48+
sec, err := vault.Auth().Login(context.Background(), auth)
49+
if err != nil {
50+
return errors.Wrap(err, "failed to auth with ory")
51+
}
52+
53+
fmt.Println("Token:", sec.Auth.ClientToken)
54+
fmt.Println("Policies:", sec.Auth.Policies)
55+
56+
secrets, err := listSecrets(vault, object)
57+
if err != nil {
58+
return errors.Wrap(err, "failed to list secrets")
59+
}
60+
61+
for _, secret := range secrets.Data {
62+
fmt.Println("Secret metadata:", secret)
63+
}
64+
65+
secret, err := readSecret(vault, object, secretName)
66+
if err != nil {
67+
return errors.Wrap(err, "failed to fetch secret")
68+
}
69+
70+
fmt.Println("Secret:", secret)
71+
72+
return nil
73+
}
74+
75+
func listSecrets(vault *api.Client, path string) (*api.Secret, error) {
76+
apiCallPath := fmt.Sprintf("secret/metadata/%s", path)
77+
return vault.Logical().List(apiCallPath)
78+
}
79+
80+
func readSecret(vault *api.Client, path, secretName string) (*api.Secret, error) {
81+
apiCallPath := fmt.Sprintf("secret/data/%s/%s", path, secretName)
82+
return vault.Logical().Read(apiCallPath)
83+
}

example/secret_viewer

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# policy that allows objects with the secret_viewer relation to access all secrets within that path
2+
3+
path "secret/data/{{identity.entity.aliases.auth_vault-plugin-auth-ory_e40b77a0.metadata.object}}*" {
4+
capabilities = ["create", "update", "read"]
5+
}
6+
7+
path "secret/metadata/{{identity.entity.aliases.auth_vault-plugin-auth-ory_e40b77a0.metadata.object}}/" {
8+
capabilities = ["list"]
9+
}

version/version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package version
22

33
import "fmt"
44

5-
const Version = "0.1.0"
5+
const Version = "0.1.1"
66

77
var (
88
Name string

0 commit comments

Comments
 (0)