1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package guestidentity
import (
"cmp"
"errors"
"fmt"
"strings"
"time"
"github.com/johnandersen777/socialweb-computer-kcp/internal/guestseed"
)
const (
WIFSimpleNSID = "com.publicdomainrelay.temp.compute.config.wif.simple"
WIFToIssue = "openbao-identity-oidc"
WIFURLRoute = "/v1/identity/oidc/token"
WIFSubjectTemplate = "actx:{actx}:plc:{did-plc-key}:role:{role}"
)
type BidConfig struct {
Type string `json:"$type"`
AcceptPath string `json:"accept_path"`
IssuerURI string `json:"issuer_uri"`
ToIssue string `json:"to_issue"`
Actx string `json:"actx"`
TokenPath string `json:"token_path"`
URLPath string `json:"url_path"`
URLRoute string `json:"url_route"`
Subject string `json:"subject"`
CreatedAt string `json:"createdAt"`
}
func SubjectFor(bidderDID, requesterDID, role string) (string, error) {
team, err := didKey(bidderDID)
if err != nil {
return "", fmt.Errorf("guestidentity: bidder DID: %w", err)
}
requester, err := didKey(requesterDID)
if err != nil {
return "", fmt.Errorf("guestidentity: requester DID: %w", err)
}
if role == "" {
return "", errors.New("guestidentity: the subject names no role")
}
return "actx:" + team + ":plc:" + requester + ":role:" + role, nil
}
func BidConfigFor(issuerURL, bidderDID, acceptPath, createdAt string) (BidConfig, error) {
team, err := didKey(bidderDID)
if err != nil {
return BidConfig{}, fmt.Errorf("guestidentity: bidder DID: %w", err)
}
ingress, err := cleanIngressURL(issuerURL)
if err != nil {
return BidConfig{}, fmt.Errorf("guestidentity: the bid config's issuer: %w", err)
}
issuer := OIDCIssuer(ingress)
acceptPath = cmp.Or(acceptPath, guestseed.AcceptPathVM)
if createdAt == "" {
createdAt = time.Now().UTC().Format(time.RFC3339)
}
return BidConfig{
Type: WIFSimpleNSID,
AcceptPath: acceptPath,
IssuerURI: issuer,
ToIssue: WIFToIssue,
Actx: team,
TokenPath: guestseed.GuestLoginTokenPath,
URLPath: guestseed.OnNetworkBaseURLPath,
URLRoute: WIFURLRoute,
Subject: WIFSubjectTemplate,
CreatedAt: createdAt,
}, nil
}
func didKey(did string) (string, error) {
did = strings.TrimSpace(did)
if !strings.HasPrefix(did, "did:") {
return "", fmt.Errorf("%q is not a DID", did)
}
parts := strings.Split(did, ":")
if len(parts) < 3 || parts[1] == "" || parts[len(parts)-1] == "" {
return "", fmt.Errorf("%q names no identifier", did)
}
return parts[len(parts)-1], nil
}