in assertion/pkg/tasks/assertion/sign.go [51:144]
func (t *Sign) Run(ctx context.Context) error {
// Check arguments
if t.VaultClient == nil {
return fmt.Errorf("vault client must not be nil")
}
if t.TransitKeyName == "" {
return fmt.Errorf("transit key name is mandatory")
}
if t.Subject == "" {
return fmt.Errorf("subject must not be blank")
}
if len(t.Audiences) == 0 {
return fmt.Errorf("audiences must not be empty")
}
if t.Expiration < 1*time.Minute {
t.Expiration = 1 * time.Minute
}
if t.Expiration > 15*time.Minute {
t.Expiration = 15 * time.Minute
}
// Retrieve content reader
reader, err := t.ContentReader(ctx)
if err != nil {
return fmt.Errorf("unable to open content for read: %w", err)
}
// Check input as json
var body map[string]interface{}
if err = json.NewDecoder(reader).Decode(&body); err != nil {
return fmt.Errorf("unable to decode input content as JSON: %w", err)
}
// Retrieve public key
pubKey, version, err := jwtvault.GetPublicKey(t.VaultClient, "assertions", t.TransitKeyName)
if err != nil {
return fmt.Errorf("unable to retrieve public key: %w", err)
}
// Allocate opaque signer
opaqueSigner := jwtvault.Signer(t.VaultClient, "assertions", t.TransitKeyName, pubKey)
// Get Public key
alg := jose.SignatureAlgorithm(opaqueSigner.Public().Algorithm)
signer, err := jose.NewSigner(
jose.SigningKey{
Algorithm: alg,
Key: &jose.JSONWebKey{
Algorithm: string(alg),
Key: opaqueSigner,
KeyID: fmt.Sprintf("vault:assertions:%s:v%d", t.TransitKeyName, version),
Use: "sig",
},
},
&jose.SignerOptions{
EmbedJWK: true,
ExtraHeaders: map[jose.HeaderKey]interface{}{
jose.HeaderType: assertionHeaderType,
},
},
)
if err != nil {
return fmt.Errorf("unable to allocate token signer: %w", err)
}
// Generate token
now := time.Now()
assertion, err := jwt.Signed(signer).Claims(body).Claims(&jwt.Claims{
ID: uniuri.NewLen(16),
Expiry: jwt.NewNumericDate(now.Add(t.Expiration)),
IssuedAt: jwt.NewNumericDate(now),
NotBefore: jwt.NewNumericDate(now.Add(-1 * time.Second)),
Issuer: "harp-assertion",
Subject: t.Subject,
Audience: jwt.Audience(t.Audiences),
}).CompactSerialize()
if err != nil {
return fmt.Errorf("unable to sign final assertion: %w", err)
}
// Allocate writer
writer, err := t.OutputWriter(ctx)
if err != nil {
return fmt.Errorf("unable to initialize output writer: %w", err)
}
// Dump to writer
if _, err := fmt.Fprintf(writer, "%s", assertion); err != nil {
return fmt.Errorf("unable to write assertion to writer: %w", err)
}
// No error
return nil
}