This project enables SPIRE Credential Composers to be written in CEL
This code is very early in development and is very experimental. Please do not use it in production yet. Please do consider testing it out, provide feedback, and maybe provide fixes.
The following root level variables are defined:
- request - spire.plugin.server.credentialcomposer.v1.ComposeWorkloadJWTSVIDRequest
- trust_domain - string, the trust domain of the server
- spiffe_trust_domain - string, the trust domain in spiffe://<trust_domain> format
request has the following properties:
- spiffe_id - string
- attributes - spire.plugin.server.credentialcomposer.v1.JWTSVIDAttributes
request.attributes has the following properties:
- claims - map(dyn, dyn)
The standard macros are available.
Some ext macros are also availabe:
Custom macros are provided:
- mapOverrideEntries - Runs on a map, give it another map and it will override settings in the first map with the second. It is a shallow override, no merging is performed.
- uuidgen - generate a v4(random) uuid
Currently only the spire.plugin.server.credentialcomposer.v1.ComposeWorkloadJWTSVIDResponse
type is
supported. It must be completely filled out. Other shortcut options may be added in the future.
This example adds newkey=newvalue
to the token.
CredentialComposer "cel" {
plugin_cmd = "spire-credentialcomposer-cel"
plugin_checksum = ""
plugin_data {
jwt {
expression_string = <<EOB
spire.plugin.server.credentialcomposer.v1.ComposeWorkloadJWTSVIDResponse{
attributes: spire.plugin.server.credentialcomposer.v1.JWTSVIDAttributes{
claims: request.attributes.claims.mapOverrideEntries({
'newkey': "newvalue"
})
}
}
EOB
}
}
}
Some clients want a JTI property. Add one.
SPIRE Server Config:
CredentialComposer "cel" {
plugin_cmd = "spire-credentialcomposer-cel"
plugin_checksum = ""
plugin_data {
jwt {
expression_string = <<EOB
spire.plugin.server.credentialcomposer.v1.ComposeWorkloadJWTSVIDResponse{
attributes: spire.plugin.server.credentialcomposer.v1.JWTSVIDAttributes{
claims: request.attributes.claims.mapOverrideEntries({"jti": uuidgen()})
}
}
EOB
}
}
}
In this example, we conditionally add a policy propery that is a list of properties as per the Minio OIDC documentation. The spiffe id path must start with /minio/ and everything after will be used as the policy name.
For example, spiffe://example.org/minio/readonly will add to the token policy: ["readonly"]
.
SPIRE Server Config:
CredentialComposer "cel" {
plugin_cmd = "spire-credentialcomposer-cel"
plugin_checksum = ""
plugin_data {
jwt {
expression_string = <<EOB
spire.plugin.server.credentialcomposer.v1.ComposeWorkloadJWTSVIDResponse{
attributes: spire.plugin.server.credentialcomposer.v1.JWTSVIDAttributes{
claims: request.attributes.claims.mapOverrideEntries(
request.spiffe_id.startsWith(spiffe_trust_domain + "/minio/")?
{'policy': [request.spiffe_id.substring(spiffe_trust_domain.size() + 7)]}:
{}
)
}
}
EOB
}
}
}
cel.bind(varname, valueforvar,
logic here
)
X.transformMap(k, v, k != 'abc', v)
X.transformMap(k, v, k == 'abc'? 72: v)