meshauth

package module
v0.0.0-...-068faf5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 29, 2024 License: Apache-2.0 Imports: 42 Imported by: 30

README

Minimal mesh-focused auth library

This is an attempt to have a small, low-resource/WASM friendly library with no external dependencies encapsulating the most common mesh auth and provisioning patterns.

The code is in large part based on/forked from Istio and few of my projects, to remove dependencies and keep a minimal package for native mesh integration.

Provisioning and config are sometimes separated from auth - but it is safer and simpler and treat both as part of the 'security' layer. This package will attempt to bootstrap config using environment-provided certificate and secrets and provides support for config updates using signed messages.

Goals

  • minimal code - only auth features commonly used in mesh with no external dependency
  • minimal user config - auto-detect as much as possible from environment.
  • clean and commented interactions with external systems
  • support Spiffee, DNS and Matter IOT certificates

Environment auto detection and configuration

A mesh application may be deployed in multiple environments and requires a number of user-specific configs - trust domain, namespace, cluster names, etc. Setting it manually adds complexity to the helm/install charts, and is easy to get wrong with major negative impact.

Istio automates this using injection - adding a number of volumes and environemnt variables. While some names are istio specific and not ideal, it is a good starting point and can be gradually improved.

Istio has evolved and has to maintain backward compat - a lot of the env variables are duplicated, redundant or not really needed in all cases.

The current 'best practice' is to rely on a platform or CSI provider for client
certificates. In the absence of it, the app can authenticate using JWTs - it is possible to get them from TokenRequest (giving each service account permission to get tokens for itself), mounted tokens or platform metadata service.

The certificate and JWTs encode namespace, trust domain, service account info - and may include cluster and project info.

Istio environment lists all settings, only a subset will be required depending on the platform.

Environment and Defaults
  • Root certificates for mesh communication: - /var/run/secrets/.... (platform provided roots), /etc/ssl/certs/ca-certificates.crt (Istio injected pods default), XDS_ROOT_CA, CA_ROOT_CA, system certificates.

  • Workload identity: cert provisioned by CertManager, Istio, etc

  • Trust domain: extracted from cert or JWT, TRUST_DOMAIN. For GKE expected to be PROJECT_ID.svc.id.goog format.

  • Namespace: POD_NAMESPACE, extracted from cert/JWT

  • Pod name: POD_NAME, hostname

  • Service account: SERVICE_ACCOUNT, extracted from cert/JWT

Certificate provider

In the absence of a 'platform certificate', the app should initiate 'commisioning'. This is provided by separate libraries, since it depends on gRPC ( ligher versions also available for smaller binary size).

  • Default is istiod.istio-system.svc:15012, using the JWT in ...

Integration

Plugins:

  • discovery mechanisms for destination metadata (for example XDS).
  • certificate provisioning
  • transports

Certificates

The code will lookup certificates in the locations used in Istio/GKE and generate certs for self-signed or testing. Includes the minimal CA code, similar to Citadel.

JWT

This library includes very minimal code to parse/verify JWT and extract info. It is not complete or intended as a general library - just as a minimal one, focused for the tokens used in K8S/Istio.

Provisioning and bootstraping

Mesh auth provisioning involves configuring a core set of options:

  • mesh and k8s root certificates
  • private key or JWT
  • a set of trusted servers for CA, XDS and further configuration.

The certs/JWT also include identity information that can be extracted - trust domain, namespace, etc.

Webpush

This package also include the basic primitives for using Webpush - crypto and VAPID. While webpush is primarily used for push messages to browsers, it is a very interesting mechanism for mesh config and events.

STS

This is one of the more complicated pieces, getting google access tokens based on a GKE token.

  1. STS authentication starts with a GKE JWT with 'PROJECT.svc.id.goog' scope. You can mount it, or get it in exchange for the default token.
  2. 'securetoken' API can exchange the token with a 'federated access token' This token can be used by some services, including in IAM policy bindings. In particular, it can be used with "workloadIdentiyUser" permission, to get tokens for another GSA.
  3. Get token for a GSA, using https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/%s - either generateAccessToken or generateIdToken

It requires 3 round-trips, but can be cached and pre-fetched.

The most important is the federated exchange, which requires a token with PROJECT_ID.svc.id.goog audience issued by a GKE cluster. Other IDP providers can be used as well - with an associated federation config.

The federated token is a google access token associated with the 'foreign' K8S identity which can be used directly by some services, or exchanged with a regular GSA that allows delegation.



$ kubectl -n validation-temp-ns -c istio-proxy exec sleep-6758c4cb78-2gtpp -- \
  cat /var/run/secrets/tokens/istio-token >  istio-token

$ curl -v https://securetoken.googleapis.com/v1/identitybindingtoken -HContent-Type:application/json -d @exch.json


{"audience":"identitynamespace:costin-istio.svc.id.goog:https://container.googleapis.com/v1/projects/costin-istio/locations/us-west1-c/clusters/istio-test",
"subjectToken":"$(cat ISTIO_TOKEN)",
"grantType":"urn:ietf:params:oauth:grant-type:token-exchange",
"requestedTokenType":"urn:ietf:params:oauth:token-type:access_token",
"scope":"https://www.googleapis.com/auth/cloud-platform",
"subjectTokenType":"urn:ietf:params:oauth:token-type:jwt"}


Response:
{"access_token":"ya29.d.Ks...",
"issued_token_type":"urn:ietf:params:oauth:token-type:access_token",
"token_type":"Bearer",
"expires_in":3600}



Documentation

Index

Constants

View Source
const BearerPrefix = "Bearer "
View Source
const ContextKey = "meshAuth"
View Source
const Default = "default"

Variables

View Source
var (
	Debug = false

	// Client used for local node ( MDS, etc) - not encrypted
	LocalHttpClient *http.Client
)
View Source
var (
	// TokenExchangeGrantType is the required value for "grant_type" parameter in a STS request.
	TokenExchangeGrantType = "urn:ietf:params:oauth:grant-type:token-exchange"

	// SubjectTokenTypeJWT is the required token type in a STS request.
	SubjectTokenTypeJWT = "urn:ietf:params:oauth:token-type:jwt"

	AccessTokenType = "urn:ietf:params:oauth:token-type:access_token"
)
View Source
var (
	DefaultChanSize int32 = 100
)
View Source
var (
	GCP_SCOPE = "https://www.googleapis.com/auth/cloud-platform"
)
View Source
var (
	MESH_NETWORK = []byte{0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0, 0x00}
)
View Source
var (
	TransientIssuerError = errors.New("transient issuer error")
)

Functions

func GetSAN

func GetSAN(c *x509.Certificate) ([]string, error)

func IDFromCert

func IDFromCert(c []*x509.Certificate) string

func IDFromPublicKeyBytes

func IDFromPublicKeyBytes(m []byte) string

func JwtRawParse

func JwtRawParse(tok string) (head *JWTHead, jwt *JWT, payload []byte, sig []byte, err error)

JwtRawParse will parse the JWT and extract the elements. WILL NOT VERIFY. From go-oidc/verify.go

func MarshalPrivateKey

func MarshalPrivateKey(priv crypto.PrivateKey) []byte

MarshalPrivateKey returns the PEM encoding of the key

func MarshalPublicKey

func MarshalPublicKey(key crypto.PublicKey) []byte

Convert a PublicKey to a marshalled format - in the raw format. - 32 byte ED25519 - 65 bytes EC256 ( 0x04 prefix ) - DER RSA key (PKCS1)

Normally the key is available from request or response TLS.PeerCertificate[0]

func ParseAuthorization

func ParseAuthorization(auth string) (string, string, map[string]string)

ParseAuthorization splits the Authorization header, returning the scheme and parameters. Used with the "scheme k=v,k=v" format.

func ParseXFCC

func ParseXFCC(val string) map[string]string

ParseXFCC is a minimal (and probably buggy) parser for XFCC envoy header. It does not deal with quoted strings including special chars (,;=). Istio certs are safe.

func Pub2ID

func Pub2ID(pub []byte) uint64

Generate a 8-byte identifier from a public key

func Pub2VIP

func Pub2VIP(pub []byte) net.IP

Convert a public key to a VIP. This is the primary WorkloadID of the nodes. Primary format is the 64-byte EC256 public key.

For RSA, the ASN.1 format of the byte[] is used. For ED, the 32-byte raw encoding.

func PublicKey

func PublicKey(key crypto.PrivateKey) crypto.PublicKey

func PublicKeyBase32SHA

func PublicKeyBase32SHA(key crypto.PublicKey) string

PublicKeyBase32SHA returns a node WorkloadID based on the public key of the node - 52 bytes base32.

func RawToCertChain

func RawToCertChain(rawCerts [][]byte) ([]*x509.Certificate, error)

func SPKIFingerprint

func SPKIFingerprint(key crypto.PublicKey) string

Return the SPKI fingerprint of the key https://www.rfc-editor.org/rfc/rfc7469#section-2.4

Can be used with "ignore-certificate-errors-spki-list" in chrome

openssl x509 -pubkey -noout -in <path to PEM cert> | openssl pkey -pubin -outform der \
  | openssl dgst -sha256 -binary | openssl base32Enc -base64

sha256/BASE64

func SendMessage

func SendMessage(hc *http.Client, subs string, vapid *MeshAuth, show bool, msg string)

Send an encrypted message to a node.

func ToMeta

func ToMeta(t string) map[string]string

func TokenPayload

func TokenPayload(jwt string) string

TokenPayload returns the decoded token. Used for logging/debugging token content, without printing the signature.

func Verify

func Verify(data []byte, pub []byte, sig []byte) error

Verify checks the data is signed with the public key pub can be a 64 byte EC256 or 32 byte ED25519

func VerifySelfSigned

func VerifySelfSigned(chain []*x509.Certificate) (crypto.PublicKey, error)

VerifySelfSigned verifies the certificate chain and extract the remote's public key.

Types

type AudienceOverrideTokenSource

type AudienceOverrideTokenSource struct {
	TokenSource TokenSource
	Audience    string
}

func (*AudienceOverrideTokenSource) GetToken

type AuthContext

type AuthContext struct {
	MeshAuth *MeshAuth

	// Parent
	Context context.Context

	// Slog
	Logger *slog.Logger
	Start  time.Time
}

AuthContext is a Context implementation holding auth info for a request.

func (*AuthContext) Deadline

func (a *AuthContext) Deadline() (deadline time.Time, ok bool)

func (*AuthContext) Done

func (a *AuthContext) Done() <-chan struct{}

func (*AuthContext) Err

func (a *AuthContext) Err() error

func (*AuthContext) Value

func (a *AuthContext) Value(key any) any

Value may return the AuthContext, if chained - or one of the fields. Otherwise will pass to parent.

type AuthHandlerWrapper

type AuthHandlerWrapper struct {
	// Original handler
	Handler http.Handler

	// Authn function
	Auth *Authn

	// The wrapper will use this to log events and errors.
	Logger *slog.Logger
}

Handler wraps another handler with authn and authz functions.

With otel, this is already wrapped in a telemetry wrapper, ctx can be used for tracing. The otel http instrumentation currently doesn't allow other interactions.

func (*AuthHandlerWrapper) ServeHTTP

func (h *AuthHandlerWrapper) ServeHTTP(writer http.ResponseWriter, request *http.Request)

type Authn

type Authn struct {
	Cfg *AuthnConfig

	Verify func(context.Context, *TrustConfig, string) error

	Client *http.Client

	// Issuers is the map - config is using a list
	Issuers map[string]*TrustConfig `json:-`
}

Authn handles JWK/OIDC authentication.

A server may have different Authn configs for different listeners/hosts/routes - but typically one global config is more common.

func NewAuthn

func NewAuthn(cfg *AuthnConfig) *Authn

func (*Authn) Auth

func (jauthn *Authn) Auth(actx *AuthContext, r *http.Request) error

Authn extracts credentials from request, applies the authn Rules to extact claims and sets the result in headers and context.

func (*Authn) CheckJWT

func (ja *Authn) CheckJWT(token string) (jwt *JWT, e error)

CheckJWT will validate the JWT and return the 'sub' (subject) of the token.

If the JWT is invalid - fails signature, invalid claims - error is set.

If the OIDC keys can't be fetched - a 500 response should be returned (?) This is indicated with a nil error and nil jwt.

func (*Authn) CheckJwtMap

func (a *Authn) CheckJwtMap(password string) (tok map[string]string, e error)

func (*Authn) ConvertJWKS

func (ja *Authn) ConvertJWKS(i *TrustConfig) error

func (*Authn) FetchAllKeys

func (ja *Authn) FetchAllKeys(ctx context.Context, issuers []*TrustConfig) error

Init the JWT map - can also be used to reconfigure.

func (*Authn) FetchKeys

func (ja *Authn) FetchKeys(ctx context.Context, i *TrustConfig) error

func (*Authn) UpdateKeys

func (ja *Authn) UpdateKeys(ctx context.Context, i *TrustConfig) error

UpdateKeys will populate the Keys field, by fetching the keys.

func (*Authn) UpdateWellKnown

func (ja *Authn) UpdateWellKnown(ctx context.Context, issuer string, td *TrustConfig) error

UpdateWellKnown downloads the JWKS from the well-known location Extracted from go-oidc

type AuthnConfig

type AuthnConfig struct {
	// Trusted issuers for auth.
	//
	Issuers []*TrustConfig `json:"trust,omitempty"`

	// If set, accept truncated tokens.
	// TODO: restrict to the main h2 listener, auto-set based on env.
	CloudrunIAM bool `json:"cloudruniam,omitempty"`

	// Top level audiences. The rule may have a custom audience as well, if it matches this is
	// ignored.
	// If empty, the hostname is used as a default.
	Audiences []string `json:"aud,omitempty"`
}

AuthnConfig specifies trusted sources for incoming authentication.

Common case is as a global config, but may be specified per listener.

Unlike Istio, this also covers SSH and Cert public keys - treating all signed mechanisms the same.

type AuthzRule

type AuthzRule struct {

	// Authz: Additional namespaces to allow access from.
	AllowedNamespaces []string
}

type CA

type CA struct {
	Config *CAConfig

	Private crypto.PrivateKey

	CACert *x509.Certificate

	TrustDomain string

	IntermediatesPEM []byte

	// Root certs
	CACertPEM []byte

	KeyType string

	ExtraKeyProvider func(public interface{}, id string, secret *Secret)
	// contains filtered or unexported fields
}

CA is used as an internal CA, mainly for testing and provisioning. Roughly equivalent with a simplified Istio Citadel.

Istio CA uses 2 kinds of roots: - direct - using istio-ca-secret.istio-system secret - intermediate - using cacerts.istio-system

Istio used to stores the files in /etc/cacerts - there are 3 or 4 files: ca-key.pem - root or intermediary key ca-cert.pem - single certificate associated with ca-key. cert-chain.pem - will be appended to all generated certificates - should be a chain path to the root, not including ca-cert ca-cert.pem - the root key (top root)

More recent versions of Istio are compatible with CertManager.

func CAFromEnv

func CAFromEnv(dir string) *CA

func NewCA

func NewCA(cfg *CAConfig) *CA

NewCA creates a new CA. Keys must be loaded.

func NewTempCA

func NewTempCA(trust string) *CA

NewTempCA creates a temporary/test CA.

func (*CA) GetToken

func (a *CA) GetToken(ctx context.Context, aud string) (string, error)

func (*CA) HandleJWK

func (a *CA) HandleJWK(w http.ResponseWriter, r *http.Request)

OIDC JWKS handler - returns the

func (*CA) Init

func (ca *CA) Init(dir string) error

func (*CA) NewCertificate

func (ca *CA) NewCertificate(w http.ResponseWriter, r *http.Request)

NewCertificate returns a Secret including certificates and optionally a private key.

WIP

If the request has a public key, it will be used for the certs.

V3: further simplification, certificates are just a APIserver extension using Secret as interface. The cert is reflected from the request authentication. Clients don't have any control (expected to be config-less) - the server policy decides.

func (*CA) NewID

func (ca *CA) NewID(ns, sa string, dns []string) *MeshAuth

New ID creates a new MeshAuth, with a certificate signed by this CA

The cert will include both Spiffe identiy and DNS SANs.

func (*CA) NewIntermediaryCA

func (ca *CA) NewIntermediaryCA(trust, cluster string) *CA

NewIntermediaryCA creates a cert for an intermediary CA.

func (*CA) NewRoot

func (ca *CA) NewRoot()

NewRoot initializes the root CA.

func (*CA) NewTLSCert

func (ca *CA) NewTLSCert(ns, sa string, dns []string) (*tls.Certificate, []byte, []byte)

NewTLSCert creates a new cert from this CA.

func (*CA) Save

func (ca *CA) Save(dir string) error

func (*CA) SetCert

func (ca *CA) SetCert(privPEM, certPEM []byte) error

SetCert will Init an existing root CA from bytes.

type CAConfig

type CAConfig struct {
	// TrustDomain to use in certs.
	// Should not be 'cluster.local' - but a real FQDN
	TrustDomain string

	// Location of the CA root - currently a dir path.
	//
	RootLocation string
}

type ConfigMap

type ConfigMap struct {
	ObjectMeta
	Data map[string]string `json:"data"`
}

type ContextDialer

type ContextDialer interface {
	// Dial with a context based on tls package - 'once successfully
	// connected, any expiration of the context will not affect the
	// connection'.
	DialContext(ctx context.Context, net, addr string) (net.Conn, error)
}

ContextDialer is same with x.net.proxy.ContextDialer Used to create the actual connection to an address using the mesh. The result may have metadata, and be an instance of util.Stream.

A uGate implements this interface, it is the primary interface for creating streams where the caller does not want to pass custom metadata. Based on net and addr and handshake, if destination is capable we will upgrade to BTS and pass metadata. This may also be sent via an egress gateway.

For compatibility, 'net' can be "tcp" and addr a mangled hostname:port Mesh addresses can be identified by the hostname or IP6 address. External addresses will create direct connections if possible, or use egress server.

TODO: also support 'url' scheme

type ContextGetter

type ContextGetter interface {
	Context() context.Context
}

ContextGetter allows getting a Context associated with a stream or request or other high-level object. Based on http.Request

type CreateTokenRequest

type CreateTokenRequest struct {
	Spec CreateTokenRequestSpec `json:"spec"`
}

type CreateTokenRequestSpec

type CreateTokenRequestSpec struct {
	Audiences []string `json:"audiences"`
}

type CreateTokenResponse

type CreateTokenResponse struct {
	Status CreateTokenResponseStatus `json:"status"`
}

type CreateTokenResponseStatus

type CreateTokenResponseStatus struct {
	Token string `json:"token"`
}

type Credential

type Credential struct {
	// Identity asserted by this credential - if not set inferred from JWT/cert
	Principal string

	// SetCert the cert credential from this directory (or URL)
	// The 'default' credential will use well-known locations.
	// All other certs are either explicit or relative to CertDir/NAME
	CertLocation string

	// If set, the token source will be used.
	// Using gRPC interface which returns the full auth string, not only the token
	//
	TokenProvider PerRPCCredentials `json:-`

	// Static token to use. May be a long lived K8S service account secret or other long-lived creds.
	// Alternative: static token source
	Token string

	// TokenSource is the name of the token provier.
	// If set, a token source with this name is used. The provider must be set in MeshEnv.AuthProviders
	TokenSource string
}

Credential identifies a source of client private info to use for authentication with a destination.

It can be a shared secret (token), private key, etc.

type Dest

type Dest struct {

	// Addr is the address of the destination.
	//
	// For HTTP, Addr is the URL, including any required path prefix, for the destination.
	//
	// For TCP, Addr is the TCP address - VIP:port or DNS:port format. tcp:// is assumed.
	//
	// For K8S service it should be in the form serviceName.namespace.svc:svcPort
	// The cluster suffix is assumed to be 'cluster.local' or the custom k8s suffix,
	// equivalent to cluster.server in kubeconfig.
	//
	// This can also be an 'original dst' address for individual endpoints.
	//
	// Individual IPs (real or relay like waypoints or egress GW, etc) will be in
	// the info.addrs field.
	Addr string `json:"addr,omitempty"`

	// Proto determines how to talk with the Dest.
	// Could be 'hbone' (compat with Istio), 'h2c', 'h2', 'ssh', etc.
	// If not set - Dial will use regular TCP or TLS, depending on the other settings.
	Proto string `json:"protocol,omitempty"`

	// Sources of trust for validating the peer destination.
	// Typically, a certificate - if not set, SYSTEM certificates will be used for non-mesh destinations
	// and the MESH certificates for destinations using one of the mesh domains.
	// If not set, the nodes' trust config is used.
	TrustConfig *TrustConfig `json:"trust,omitempty"`

	// Expected SANs - if not set, the DNS host in the address is used.
	// For mesh FQDNs, the namespace will be checked ( second part of the FQDN )
	DNSSANs []string `json:"dns_san,omitempty"`
	//IPSANs  []string `json:"ip_san,omitempty"`
	URLSANs []string `json:"url_san,omitempty"`

	// SNI to use when making the request. Defaults to hostname in Addr
	SNI string `json:"sni,omitempty"`

	ALPN []string `json:"alpn,omitempty"`

	// Location is set if the cluster has a default location (not global).
	Location string `json:"location,omitempty"`

	// If empty, the cluster is using system certs or SPIFFE CAs - as configured in
	// MeshAuth.
	//
	// Otherwise, it's the configured root certs list, in PEM format.
	// May include multiple concatenated roots.
	//
	// TODO: allow root SHA only.
	CACertPEM []byte `json:"ca_cert,omitempty"`

	// timeout for new network connections to endpoints in cluster
	ConnectTimeout time.Duration `json:"connect_timeout,omitempty"`
	TCPKeepAlive   time.Duration `json:"tcp_keep_alive,omitempty"`
	TCPUserTimeout time.Duration `json:"tcp_user_timeout,omitempty"`

	// Default values for initial window size, initial window, max frame size
	InitialConnWindowSize int32  `json:"initial_conn_window,omitempty"`
	InitialWindowSize     int32  `json:"initial_window,omitempty"`
	MaxFrameSize          uint32 `json:"max_frame_size,omitempty"`

	Labels map[string]string `json:"labels,omitempty"`

	// If set, Bearer tokens will be added.
	TokenProvider TokenSource `json:-`

	// If set, a token source with this name is used. The provider must be set in MeshEnv.AuthProviders
	// If not found, no tokens will be added. If found, errors getting tokens will result
	// in errors connecting.
	// In K8S - it will be the well-known token file.
	TokenSource string `json:"tokens,omitempty"`

	// WebpushPublicKey is the client's public key. From the getKey("p256dh") or keys.p256dh field.
	// This is used for Dest that accepts messages encrypted using webpush spec, and may
	// be used for validating self-signed destinations - this is expected to be the public
	// key of the destination.
	// Primary public key of the node.
	// EC256: 65 bytes, uncompressed format
	// RSA: DER
	// ED25519: 32B
	// Used for sending encryted webpush message
	// If not known, will be populated after the connection.
	WebpushPublicKey []byte `json:"pub,omitempty"`

	// Webpush Auth is a secret shared with the peer, used in sending webpush
	// messages.
	WebpushAuth []byte `json:"auth,omitempty"`

	// If set, the destination is using HTTP protocol - and this is the roundtripper to use.
	// HttpClient() returns a http client initialized for this destination.
	// For special cases ( reverse connections in h2r ) it will be a *http2.ClientConn.
	//
	RoundTripper          http.RoundTripper `json:-`
	InsecureSkipTLSVerify bool              `json:"insecure,omitempty"`

	Dialer ContextDialer `json:-`

	// L4Secure is set if the destination can be reached over a secure L4 network (ambient, VPC, IPSec, secure CNI, etc)
	L4Secure bool `json:"l4secure,omitempty"`

	// Last packet or registration from the peer.
	LastSeen time.Time `json:"-"`

	Backoff time.Duration `json:"-"`
	Dynamic bool          `json:"-"`
	// contains filtered or unexported fields
}

Dest represents a destination and associated security info.

In Istio this is represented as DestinationRule, Envoy - Cluster, K8S Service (the backend side).

This is primarily concerned with the security aspects (auth, transport), and include 'trusted' attributes from K8S configs or JWT/cert.

K8S clusters can be represented as a Dest - rest.Config Host is Addr, CACertPEM

Unlike K8S and Envoy, the port is not required.

This is part of the config - either static or on-demand. The key is the virtual address or IP:port that is either captured or set as backendRef in routes.

func InitK8SInCluster

func InitK8SInCluster(ma *MeshAuth) (*Dest, error)

InitK8SInCluster will check if running in cluster, and init based on the K8S environment files.

func WebpushSubscriptionToDest

func WebpushSubscriptionToDest(b []byte) (*Dest, error)

Subscription holds the useful values from a PushSubscription object acquired from the browser.

https://w3c.github.io/push-api/

Returned as result of /subscribe WebpushSubscriptionToDest is a convenience function that decodes a JSON encoded PushSubscription object acquired from the browser

func (*Dest) AddCACertPEM

func (d *Dest) AddCACertPEM(pems []byte) error

func (*Dest) AddToken

func (c *Dest) AddToken(ma *MeshAuth, req *http.Request, aut string) error

AddToken will add a token to the request, using the 'token source' of the destination.

func (*Dest) BackoffReset

func (n *Dest) BackoffReset()

func (*Dest) BackoffSleep

func (n *Dest) BackoffSleep()

func (*Dest) CertPool

func (d *Dest) CertPool() *x509.CertPool

func (*Dest) DialTLS

func (d *Dest) DialTLS(a *MeshAuth, nc net.Conn) (*tls.Conn, error)

WIP

func (*Dest) GetCACertPEM

func (d *Dest) GetCACertPEM() []byte

func (*Dest) HttpClient

func (d *Dest) HttpClient() *http.Client

HttpClient returns a http client configured to talk with this Dest using a secure connection. - if CACertPEM is set, will be used instead of system

The client is cached in Dest.

func (*Dest) Load

func (d *Dest) Load(ctx context.Context, obj interface{}, kind, ns string, name string) error

Load will populate the Secret object from a K8S-like service. This also works with real K8S.

'kind' can be 'configmap', 'secret', etc for using K8S-style URL format

func (*Dest) RoundTrip

func (d *Dest) RoundTrip(r *http.Request) (*http.Response, error)

type Duration

type Duration struct {
	// Signed seconds of the span of time. Must be from -315,576,000,000
	// to +315,576,000,000 inclusive. Note: these bounds are computed from:
	// 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
	Seconds int64 `json:"seconds"`
}

From tokenexchangeplugin.go

type Event

type Event struct {
	Type EventType

	// Object is:
	//  * If Type is Added or Modified: the new state of the object.
	//  * If Type is Deleted: the state of the object immediately before deletion.
	//  * If Type is Bookmark: the object (instance of a type being watched) where
	//    only ResourceVersion field is set. On successful restart of watch from a
	//    bookmark resourceVersion, client is guaranteed to not get repeat event
	//    nor miss any events.
	//  * If Type is Error: *api.Status is recommended; other types may make sense
	//    depending on context.
	Object interface{}
}

Event represents a single event to a watched resource. +k8s:deepcopy-gen=true

type EventType

type EventType string

EventType defines the possible types of events.

const (
	Added    EventType = "ADDED"
	Modified EventType = "MODIFIED"
	Deleted  EventType = "DELETED"
	Bookmark EventType = "BOOKMARK"
	Error    EventType = "ERROR"
)

type FileTokenSource

type FileTokenSource struct {
	TokenFile string
}

File or static token source

func (*FileTokenSource) GetToken

func (s *FileTokenSource) GetToken(context.Context, string) (string, error)

type Instance

type Instance struct {
	SSHKeys    string `json:"ssh-keys"`
	InstanceID int    `json:"id"`
	Zone       string `json:"zone"`
	Name       string `json:"name"`
}

type JSONWebKeySet

type JSONWebKeySet struct {
	Keys []rawJSONWebKey `json:"keys"`
}

type JWT

type JWT struct {
	//An "aud" (Audience) claim in the token MUST include the Unicode
	//serialization of the origin (Section 6.1 of [RFC6454]) of the push
	//resource URL.  This binds the token to a specific push service and
	//ensures that the token is reusable for all push resource URLs that
	//share the same origin.
	// In K8S it is an array !
	Aud MultiString `json:"aud,omitempty"`

	//If the application server wishes to provide contact details, it MAY
	//include a "sub" (Subject) claim in the JWT.  The "sub" claim SHOULD
	//include a contact URI for the application server as either a
	//"mailto:" (email) [RFC6068] or an "https:" [RFC2818] URI.
	//
	// For K8S, system:serviceaccount:NAMESPACE:KSA
	Sub string `json:"sub,omitempty"`

	// Max 24h
	Exp int64 `json:"exp,omitempty"`
	IAT int64 `json:"iat,omitempty"`

	// Issuer - for example kubernetes/serviceaccount.
	Iss string `json:"iss,omitempty"`

	Email string `json:"email,omitempty"`

	EmailVerified bool `json:"email_verified,omitempty"`

	//  \"kubernetes.io\":{\"namespace\":\"default\",\"serviceaccount\":{\"name\":\"default\",
	// \"uid\":\"a47d63f6-29a4-4e95-94a6-35e39ee6d77c\"}},
	K8S *K8SAccountInfo `json:"kubernetes.io,omitempty"`

	Name string `json:"kubernetes.io/serviceaccount/service-account.name,omitempty"`

	Head    *JWTHead `json:"-"`
	Signed  []byte   `json:"-"`
	Payload []byte   `json:"-"`
	Sig     []byte   `json:"-"`
	Raw     string   `json:"-"`
}

JWT includes minimal field for a JWT, primarily for extracting iss for the exchange.

This is also used with K8S JWTs, which use multi-string.

func CheckVAPID

func CheckVAPID(tok string, now time.Time) (jwt *JWT, pub []byte, err error)

CheckVAPID verifies the signature and returns the token and public key. expCheck should be set to current time to set expiration

Data is extracted from VAPID header - 'vapid' scheme and t/k params

Does not check audience or other parms.

func DecodeJWT

func DecodeJWT(jwt string) *JWT

DecodeJWT decodes the content of a token. No signature checks.

func JWTVerifySignature

func JWTVerifySignature(h *JWTHead, b *JWT, txt []byte, sig []byte, pk crypto.PublicKey) (*JWT, error)

JWTVerifySignature will verify "txt" using a public key or other verifiers.

func (*JWT) Audience

func (j *JWT) Audience() string

func (*JWT) CheckAudience

func (j *JWT) CheckAudience(audExpected []string) bool

checkAudience() returns true if the audiences to check are in the expected audiences. Otherwise, return false.

func (*JWT) Expiry

func (j *JWT) Expiry() time.Time

func (*JWT) K8SInfo

func (j *JWT) K8SInfo() (string, string)

func (*JWT) KSA

func (j *JWT) KSA() (string, string)

func (*JWT) Sign

func (jwt *JWT) Sign(privateKey crypto.PrivateKey) string

func (*JWT) String

func (j *JWT) String() string

func (*JWT) VerifySignature

func (j *JWT) VerifySignature(pk crypto.PublicKey) error

type JWTHead

type JWTHead struct {
	Typ string `json:"typ"`
	Alg string `json:"alg,omitempty"`
	Kid string `json:"kid"`
}

First part of the token.

type JWTTokenCache

type JWTTokenCache struct {
	TokenSource TokenSource
	// contains filtered or unexported fields
}

func (*JWTTokenCache) Token

func (c *JWTTokenCache) Token(ctx context.Context, aud string) (string, error)

type K8SAccountInfo

type K8SAccountInfo struct {
	Namespace string `json:"namespace,omitempty"`
}

type K8STokenSource

type K8STokenSource struct {
	// Dest is the common set of properties for any server we connect as client.
	// (hostname or IP, expected SANs and roots ).
	*Dest

	// Namespace and KSA - the 'cluster' credentials must have the RBAC permissions.
	// The user in the Cluster is typically admin - or may be the
	// same user, but have RBAC to call TokenRequest.
	Namespace      string
	ServiceAccount string
}

K8STokenSource provides authentication and basic communication with a K8S cluster. The main purpose is to handle what is needed for auth and provisioning - loading secrets and config maps and getting tokens.

K8S is an identity provider, and supports multiple credential types for exchange. If the app runs in K8S, it expects to find info in well-known locations. If it doesn't - it expects to have a KUBECONFIG or ~/.kube/config - or some other mechanism to get the address/credentials.

func (*K8STokenSource) Do

func (k *K8STokenSource) Do(r *http.Request) ([]byte, error)

func (*K8STokenSource) GetToken

func (k *K8STokenSource) GetToken(ctx context.Context, aud string) (string, error)

func (*K8STokenSource) GetTokenRaw

func (k *K8STokenSource) GetTokenRaw(ctx context.Context, ns, name, aud string) (string, error)

GetTokenRaw returns a K8S JWT with specified namespace, name and audience. Caller must have the RBAC permission to act as the name.ns.

Equivalent curl request:

token=$(echo '{"kind":"TokenRequest","apiVersion":"authentication.k8s.io/v1","spec":{"audiences":["istio-ca"], "expirationSeconds":2592000}}' | \
   kubectl create --raw /api/v1/namespaces/default/serviceaccounts/default/token -f - | jq -j '.status.token')

type ListMeta

type ListMeta struct {
	// selfLink is a URL representing this object.
	// Populated by the system.
	// Read-only.
	//
	// DEPRECATED
	// Kubernetes will stop propagating this field in 1.20 release and the field is planned
	// to be removed in 1.21 release.
	// +optional
	SelfLink string `json:"selfLink,omitempty" protobuf:"bytes,1,opt,name=selfLink"`

	// String that identifies the server's internal version of this object that
	// can be used by clients to determine when objects have changed.
	// Value must be treated as opaque by clients and passed unmodified back to the server.
	// Populated by the system.
	// Read-only.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
	// +optional
	ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,2,opt,name=resourceVersion"`

	// continue may be set if the user set a limit on the number of items returned, and indicates that
	// the server has more data available. The value is opaque and may be used to issue another request
	// to the endpoint that served this list to retrieve the next set of available objects. Continuing a
	// consistent list may not be possible if the server configuration has changed or more than a few
	// minutes have passed. The resourceVersion field returned when using this continue value will be
	// identical to the value in the first response, unless you have received this token from an error
	// message.
	Continue string `json:"continue,omitempty" protobuf:"bytes,3,opt,name=continue"`

	// remainingItemCount is the number of subsequent items in the list which are not included in this
	// list response. If the list request contained label or field selectors, then the number of
	// remaining items is unknown and the field will be left unset and omitted during serialization.
	// If the list is complete (either because it is not chunking or because this is the last chunk),
	// then there are no more remaining items and this field will be left unset and omitted during
	// serialization.
	// Servers older than v1.15 do not set this field.
	// The intended use of the remainingItemCount is *estimating* the size of a collection. Clients
	// should not rely on the remainingItemCount to be set or to be exact.
	// +optional
	RemainingItemCount *int64 `json:"remainingItemCount,omitempty" protobuf:"bytes,4,opt,name=remainingItemCount"`
}

ListMeta describes metadata that synthetic resources must have, including lists and various status objects. A resource may have only one of {ObjectMeta, ListMeta}.

type ListOptions

type ListOptions struct {
	// A selector to restrict the list of returned objects by their labels.
	// Defaults to everything.
	// +optional
	LabelSelector string `json:"labelSelector,omitempty" protobuf:"bytes,1,opt,name=labelSelector"`
	// A selector to restrict the list of returned objects by their fields.
	// Defaults to everything.
	// +optional
	FieldSelector string `json:"fieldSelector,omitempty" protobuf:"bytes,2,opt,name=fieldSelector"`

	// resourceVersion sets a constraint on what resource versions a request may be served from.
	// See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for
	// details.
	//
	// Defaults to unset
	// +optional
	ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,4,opt,name=resourceVersion"`

	// `sendInitialEvents=true` may be set together with `watch=true`.
	// In that case, the watch stream will begin with synthetic events to
	// produce the current state of objects in the collection. Once all such
	// events have been sent, a synthetic "Bookmark" event  will be sent.
	// The bookmark will report the ResourceVersion (RV) corresponding to the
	// set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation.
	// Afterwards, the watch stream will proceed as usual, sending watch events
	// corresponding to changes (subsequent to the RV) to objects watched.
	//
	// When `sendInitialEvents` option is set, we require `resourceVersionMatch`
	// option to also be set. The semantic of the watch request is as following:
	// - `resourceVersionMatch` = NotOlderThan
	//   is interpreted as "data at least as new as the provided `resourceVersion`"
	//   and the bookmark event is send when the state is synced
	//   to a `resourceVersion` at least as fresh as the one provided by the ListOptions.
	//   If `resourceVersion` is unset, this is interpreted as "consistent read" and the
	//   bookmark event is send when the state is synced at least to the moment
	//   when request started being processed.
	// - `resourceVersionMatch` set to any other value or unset
	//   Invalid error is returned.
	//
	// Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward
	// compatibility reasons) and to false otherwise.
	// +optional
	SendInitialEvents *bool `json:"sendInitialEvents,omitempty" protobuf:"varint,11,opt,name=sendInitialEvents"`
}

type MDS

type MDS struct {
	// Certificate and client factory.
	MeshAuth *MeshAuth

	// Addr is the address of the MDS server, including http:// or https://
	// Will detect a GCP/GKE server
	Addr string

	// For GCP MDS, request the full token content.
	UseMDSFullToken bool

	Meta sync.Map
}

MDS represents the workload metadata. It is extracted from environment: env variables, mesh config, local metadata server.

func (*MDS) GetRequestMetadata

func (s *MDS) GetRequestMetadata(ctx context.Context, aud ...string) (map[string]string, error)

GetRequestMetadata implements credentials.PerRPCCredentials This can be used for both WorkloadID tokens or access tokens - if the 'aud' containts googleapis.com, access tokens are returned.

func (*MDS) GetToken

func (s *MDS) GetToken(ctx context.Context, aud string) (string, error)

Get an WorkloadID token from platform (GCP, etc) using metadata server.

curl  -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=[AUDIENCE]" \

On GKE requires annotation: iam.gke.io/gcp-service-account=[GSA_NAME]@[PROJECT_ID] May fail and need retry

func (*MDS) HandleMDS

func (m *MDS) HandleMDS(w http.ResponseWriter, r *http.Request)

MDS emulates the GCP metadata server. MDS address is 169.254.169.254:80 - can be intercepted with iptables, or set using GCE_METADATA_HOST https://googleapis.dev/python/google-auth/latest/reference/google.auth.environment_vars.html https://pkg.go.dev/cloud.google.com/go/compute/metadata#Client.Get

gRPC library will use it if: - the env variable is set - a probe to the IP and URL / returns the proper flavor. - DNS resolves metadata.google.internal to the IP

func (*MDS) MetadataGet

func (m *MDS) MetadataGet(path string) (string, error)

GetMDS returns MDS info:

For GCP: instance/hostname - node name.c.PROJECT.internal instance/attributes/cluster-name, cluster-location project/project-id, numeric-project-id

Auth: instance/service-accounts/ - default, PROJECTID.svc.id.goog instance/service-accounts/default/identity - requires the iam.gke.io/gcp-service-account=gsa@project annotation and IAM instance/service-accounts/default/token - access token for the KSA

func (*MDS) ProjectID

func (s *MDS) ProjectID() string

func (*MDS) RequireTransportSecurity

func (s *MDS) RequireTransportSecurity() bool

func (*MDS) WorkloadName

func (mds *MDS) WorkloadName() string

Determine the workload name, using environment variables or hostname. This should be unique, typically pod-xxx-yyy

type MeshAuth

type MeshAuth struct {
	*MeshCfg

	// Primary workload ID TLS certificate and private key. Loaded or generated.
	// Default is to use EC256 certs. The private key can be used to sign JWTs.
	// The public key and sha can be used as a node identity.
	Cert *tls.Certificate

	// cached PublicKeyBase64 encoding of the public key, for EC256 VAPID.
	PublicKeyBase64 string

	// Public key as base32 SHA (52 bytes)
	PubID string

	// Node ID - pod ID, CloudRun instanceID, hostname.
	//
	// Must be DNS compatible, case insensitive, max 63
	ID string `json:"id,omitempty"`

	// Primary VIP, Created from the PublicKey key, will be included in the self-signed cert.
	VIP6 net.IP

	// Same as VIP6, but as uint64
	VIP64 uint64

	// Explicit certificates (lego), key is hostname from file
	//
	CertMap map[string]*tls.Certificate

	// GetCertificateHook allows plugging in an alternative certificate provider.
	GetCertificateHook func(host string) (*tls.Certificate, error)

	// Auth token providers
	AuthProviders map[string]TokenSource

	// Metadata about this node. Also, the default TokenSource.
	MDS *MDS

	ClientSessionCache tls.ClientSessionCache

	Stop chan struct{}

	// Location is the location of the node - derived from MDS or config.
	Location string
	// contains filtered or unexported fields
}

MeshAuth represents a workload identity and associated info required for minimal mesh-compatible security. Includes helpers for authentication and basic provisioning.

By default it will attempt to Init a workload cert, and extract info from the cert.

A workload may be associated with multiple service accounts and identity providers, and may have multiple certificates.

func FromEnv

func FromEnv(cfg *MeshCfg) (*MeshAuth, error)

FromEnv will attempt to identify and Init the certificates. This should be called from main() and for normal app use.

NewMeshAuth can be used in tests or for fine control over what cert is loaded.

- default GKE/Istio location for workload identity - /var/run/secrets/...FindC - /etc/istio/certs - $HOME/

If a cert is found, the identity is extracted from the cert. The platform is expected to refresh the cert.

If a cert is not found, Cert field will be nil, and the app should use one of the methods of getting a cert or call InitSelfSigned.

func NewMeshAuth

func NewMeshAuth(cfg *MeshCfg) *MeshAuth

NewMeshAuth initializes the auth systems based on config.

Must call SetTLSCertificate to initialize or one of the methods that finds or generates the primary identity.

func (*MeshAuth) AddRootDER

func (a *MeshAuth) AddRootDER(root []byte) error

Add a list of certificates in DER format to the root. The top signer of the workload certificate is added by default.

func (*MeshAuth) AddRoots

func (a *MeshAuth) AddRoots(rootCertPEM []byte) error

AddRoots will process a PEM file containing multiple concatenated certificates.

func (*MeshAuth) GenerateTLSConfigServer

func (a *MeshAuth) GenerateTLSConfigServer(allowMeshExternal bool) *tls.Config

GenerateTLSConfigServer is used to provide the server tls.Config for handshakes.

Will use the workload identity and do basic checks on client certs. It does not require client certs - but asks for them, and if found verifies.

If allowMeshExternal is set, will skip verification for certs with different trust domain.

func (*MeshAuth) GetCertificate

func (a *MeshAuth) GetCertificate(ctx context.Context, sni string) (*tls.Certificate, error)

GetCertificate is typically called during handshake, both server and client. "sni" will be empty for client certificates, and set for server certificates - if not set, workload id is returned.

ctx is the handshake context - may include additional metadata about the operation.

func (*MeshAuth) GetCerts

func (auth *MeshAuth) GetCerts() map[string]*tls.Certificate

Get all known certificates from local files. This is used to support lego certificates and istio.

"istio" is a special name, set if istio certs are found

func (*MeshAuth) GetToken

func (auth *MeshAuth) GetToken(ctx context.Context, aud string) (string, error)

func (*MeshAuth) HandleDisc

func (a *MeshAuth) HandleDisc(w http.ResponseWriter, r *http.Request)

OIDC discovery on .well-known/openid-configuration

func (*MeshAuth) Host2ID

func (auth *MeshAuth) Host2ID(host string) string

Host2ID converts a Host/:authority or path parameter hostname to a node ID.

func (*MeshAuth) HttpClient

func (a *MeshAuth) HttpClient(dest *Dest) *http.Client

HttpClient returns a http.Client configured based on the security settings for Dest.

func (*MeshAuth) InitCertificates

func (kr *MeshAuth) InitCertificates(ctx context.Context, certDir string) error

Common setup for cert management. After the 'mesh-env' is loaded (from env, k8s, URL) the next step is to init the workload identity. This must happen before connecting to XDS - since certs is one of the possible auth methods.

The logic is:

  • (best case) certificates already provisioned by platform. Detects GKE paths (CAS), old Istio, CertManager style If workload certs are platform-provisioned: extract trust domain, namespace, name, pod id from cert.

- Detect the WORKLOAD_SERVICE_ACCOUNT, trust domain from JWT or mesh-env - Use WORKLOAD_CERT json to Init the config for the CSR, create a CSR - Call CSRSigner. - Save the certificates if running as root or an output dir is set. This will use CAS naming convention.

If envoy + pilot-agent are used, they should be configured to use the cert files. This is done by setting "CA_PROVIDER=GoogleGkeWorkloadCertificate" when starting pilot-agent

func (*MeshAuth) InitSelfSigned

func (auth *MeshAuth) InitSelfSigned(kty string) *MeshAuth

Will init the Cert, PubID, PublicKey fields - private is in Cert.

func (*MeshAuth) NodeID

func (auth *MeshAuth) NodeID() []byte

func (*MeshAuth) NodeIDUInt

func (auth *MeshAuth) NodeIDUInt(pub []byte) uint64

func (*MeshAuth) SaveCerts

func (a *MeshAuth) SaveCerts(outDir string) error

SaveCerts will create certificate files as expected by gRPC and Istio, similar with the auto-created files.

This creates 3 files. NGinx and others also support one file, in the order cert, intermediary, key, and using hostname as the name.

func (*MeshAuth) Self

func (a *MeshAuth) Self() string

Return the self identity. Currently it's using the VIP6 format - may change. This is used in Message 'From' and in ReqContext.

func (*MeshAuth) SetCertPEM

func (a *MeshAuth) SetCertPEM(privatePEM string, chainPEMCat string) error

SetCertPEM explicitly set the certificate and key. The cert will not be rotated - use a dir to reload or call this function with fresh certs before it expires.

func (*MeshAuth) SetTLSCertificate

func (a *MeshAuth) SetTLSCertificate(cert *tls.Certificate) error

func (*MeshAuth) Sign

func (auth *MeshAuth) Sign(data []byte, sig []byte)

Sign - requires ECDSA primary key

func (*MeshAuth) SignCert

func (auth *MeshAuth) SignCert(priv crypto.PrivateKey, ca crypto.PrivateKey, sans ...string) (tls.Certificate, []byte, []byte)

func (*MeshAuth) SignCertDER

func (auth *MeshAuth) SignCertDER(pub crypto.PublicKey, caPrivate crypto.PrivateKey, sans ...string) []byte

func (*MeshAuth) Spiffee

func (a *MeshAuth) Spiffee() (*url.URL, string, string, string)

Extract the trustDomain, namespace and Name from a spiffee certificate

func (*MeshAuth) String

func (a *MeshAuth) String() string

String returns a json representation of mesh auth.

func (*MeshAuth) TLSClient

func (a *MeshAuth) TLSClient(ctx context.Context, nc net.Conn,
	dest *Dest,
	remotePub32 string) (*tls.Conn, error)

GenerateTLSConfigDest returns a custom tls config for a Dest and a context holder. This should be used with a single

func (*MeshAuth) TLSClientConf

func (a *MeshAuth) TLSClientConf(dest *Dest, sni string,
	remotePub32 string) *tls.Config

TLSClientConf returns a config for a specific cluster.

sni can override the cluster sni remotePub32 is the cert-baseed identity of a specific endpoint.

func (*MeshAuth) VAPIDToken

func (auth *MeshAuth) VAPIDToken(aud string) string

VAPIDToken creates a token with the specified endpoint, using configured Sub id and a default expiration (1h). The MeshAuth identity must be based on EC256.

Format is "vapid t=TOKEN k=PUBKEY

The optional (unauthenticated) Sub field is populated from Name@Domain or TrustDomain. The DMesh VIP is based on the public key of the signer. AUD is the URL from the subscription - for DMesh https://VIP:5228/s or https://DOMAIN:5228/s

func (*MeshAuth) WithContext

func (ma *MeshAuth) WithContext(ctx context.Context) context.Context

func (*MeshAuth) WorkloadID

func (a *MeshAuth) WorkloadID() string

type MeshCfg

type MeshCfg struct {

	// AuthnConfig defines the trust config for the node - the list of signers that are trusted for specific
	// issuers and domains, audiences, etc.
	//
	// Based on Istio jwtRules, but generalized to all signer types.
	//
	// Authz is separated - this only defines who do we trust (and policies on what we trust it for)
	//
	// Destinations and listeners may have their own AuthnConfig - this is the default.
	AuthnConfig `json:",inline"`

	// Will attempt to Init/reload certificates from this directory.
	// If empty, FromEnv will auto-detect.
	// For mounted secret of type kubernetes.io/tls, the keys are tls.key, tls.crt
	// Deprecated - Credential
	CertDir string `json:"certDir,omitempty"`

	// Trusted roots, in DER format.
	// Deprecated - AuthnConfig
	RootCertificates [][]byte `json:"roots,omitempty"`

	// Domain is extracted from the cert or set by user, used to verify
	// peer certificates. If not set, will be populated when cert is loaded.
	// Should be a real domain with OIDC keys or platform specific.
	// NOT cluster.local
	Domain string `json:"domain,omitempty"`

	DomainAliases []string `json:"domainAliases,omitempty"`

	// Namespace and Name are extracted from the certificate or set by user.
	// Namespace is used to verify peer certificates
	Namespace string `json:"namespace,omitempty"`

	// Name of the service account. Can be an email or spiffee or just the naked name.
	Name string `json:"name,omitempty"`

	// Deprecated - MDS
	ProjectID string `json:"project_id,omitempty"`
	GSA       string `json:"gsa,omitempty"`

	// Authz: Additional namespaces to allow access from. If no authz rule is set, 'same namespace'
	// and 'istio-system' are allowed.
	// Deprecated - Authz
	AllowedNamespaces []string

	// If no authz rule is set, 'same namespace' and 'istio-system' are allowed.
	Authz []*AuthzRule

	// Private key. UGate primary key is EC256, in PEM format.
	// Used for client and server auth for all protocols.
	// If not set, will be loaded from CertDir tls.key file, or auto-generated.
	Priv string `json:"priv,omitempty"`

	// PEM certificate chain
	CertBytes string `json:"cert,omitempty"`

	// DER public key
	PublicKey []byte `json:"pub,omitempty"`

	// EC256 key, in base64 format. Used for self-signed identity and webpush.
	EC256Key string
	EC256Pub string

	MDS *util.Metadata `json:"mds,omitempty"`

	// TokenProvider is a URL used to get access tokens, as a GCP-like MDS server,
	// for client.
	//
	// Default is http://169.254.169.245
	// For local dev and debugging it can be replaced.
	// It can also be a full http:// or https:// URL.
	// Deprecated - Credentials
	TokenProvider string `json:"token_source,omitempty"`

	// Dst contains pre-configured or discovered properties for destination services.
	// When running in K8S, "KUBERNETES" is set with the in-cluster config.
	// A .kube/config file can be converted to dst if a subset of auth is used.
	//
	// K8S Services, SSH hosts, etc are also represented as Dst.
	Dst map[string]*Dest `json:"dst,omitempty"`

	// Additional port listeners.
	// Routes: listen on 127.0.0.1:port
	// Ingress: listen on 0.0.0.0:port (or actual IP)
	//
	// Port proxies: will register a listener for each port, forwarding to the
	// given address.
	//
	// K8S Gateway: key is the section name (converting from list to map)
	Listeners map[string]*PortListener `json:"listeners,omitempty"`
	// contains filtered or unexported fields
}

MeshCfg is used to configure the mesh basic settings related to security.

It includes definition of listeners and cluters (dst) - with associated keys/certs. This package does not provide any protocol or listening.

func NewMeshAuthCfg

func NewMeshAuthCfg() MeshCfg

type Metadata

type Metadata struct {
	Instance Instance `json:"instance"`
}

Metadata is the root of the GCP metadata. Using it as a base, to avoid conversions and mappings.

type MultiString

type MultiString []string

func (*MultiString) MarshalJSON

func (ms *MultiString) MarshalJSON() ([]byte, error)

func (*MultiString) UnmarshalJSON

func (ms *MultiString) UnmarshalJSON(data []byte) error

type OIDCDiscDoc

type OIDCDiscDoc struct {
	// Should match the one in the URL
	Issuer string `json:"issuer,omitempty"`

	// Same as the URI in the Istio config - contains the keys.
	// Example: "https://www.googleapis.com/oauth2/v3/certs"
	JWKSURL string `json:"jwks_uri,omitempty"`

	// Not used
	AuthURL       string `json:"authorization_endpoint,omitempty"`
	DeviceAuthURL string `json:"device_authorization_endpoint,omitempty"`
	TokenURL      string `json:"token_endpoint,omitempty"`
	UserInfoURL   string `json:"userinfo_endpoint,omitempty"`

	Algorithms []string `json:"id_token_signing_alg_values_supported,omitempty"`
}

WIP: discovery document returned when fetching the 'issuer' well known location

wellKnown := strings.TrimSuffix(issuer, "/") + "/.well-known/openid-configuration"

Example: curl -v https://accounts.google.com/.well-known/openid-configuration

type ObjectMeta

type ObjectMeta struct {
	// Name must be unique within a namespace. Is required when creating resources, although
	// some resources may allow a client to request the generation of an appropriate name
	// automatically. Name is primarily intended for creation idempotence and configuration
	// definition.
	// Cannot be updated.
	// More info: http://kubernetes.io/docs/user-guide/identifiers#names
	// +optional
	Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"`

	// Namespace defines the space within each name must be unique. An empty namespace is
	// equivalent to the "default" namespace, but "default" is the canonical representation.
	// Not all objects are required to be scoped to a namespace - the value of this field for
	// those objects will be empty.
	//
	// Must be a DNS_LABEL.
	// Cannot be updated.
	// More info: http://kubernetes.io/docs/user-guide/namespaces
	// +optional
	Namespace string `json:"namespace,omitempty" protobuf:"bytes,3,opt,name=namespace"`

	// UID is the unique in time and space value for this object. It is typically generated by
	// the server on successful creation of a resource and is not allowed to change on PUT
	// operations.
	//
	// Populated by the system.
	// Read-only.
	// More info: http://kubernetes.io/docs/user-guide/identifiers#uids
	// +optional
	UID UID `json:"uid,omitempty" protobuf:"bytes,5,opt,name=uid,casttype=k8s.io/kubernetes/pkg/types.UID"`

	// An opaque value that represents the internal version of this object that can
	// be used by clients to determine when objects have changed. May be used for optimistic
	// concurrency, change detection, and the watch operation on a resource or set of resources.
	// Clients must treat these values as opaque and passed unmodified back to the server.
	// They may only be valid for a particular resource or set of resources.
	//
	// Populated by the system.
	// Read-only.
	// Value must be treated as opaque by clients and .
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
	// +optional
	ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,6,opt,name=resourceVersion"`

	// A sequence number representing a specific generation of the desired state.
	// Populated by the system. Read-only.
	// +optional
	Generation int64 `json:"generation,omitempty" protobuf:"varint,7,opt,name=generation"`

	// CreationTimestamp is a timestamp representing the server time when this object was
	// created. It is not guaranteed to be set in happens-before order across separate operations.
	// Clients may not set this value. It is represented in RFC3339 form and is in UTC.
	//
	// Populated by the system.
	// Read-only.
	// Null for lists.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	CreationTimestamp Time `json:"creationTimestamp,omitempty" protobuf:"bytes,8,opt,name=creationTimestamp"`

	// DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This
	// field is set by the server when a graceful deletion is requested by the user, and is not
	// directly settable by a client. The resource is expected to be deleted (no longer visible
	// from resource lists, and not reachable by name) after the time in this field, once the
	// finalizers list is empty. As long as the finalizers list contains items, deletion is blocked.
	// Once the deletionTimestamp is set, this value may not be unset or be set further into the
	// future, although it may be shortened or the resource may be deleted prior to this time.
	// For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react
	// by sending a graceful termination signal to the containers in the pod. After that 30 seconds,
	// the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup,
	// remove the pod from the API. In the presence of network partitions, this object may still
	// exist after this timestamp, until an administrator or automated process can determine the
	// resource is fully terminated.
	// If not set, graceful deletion of the object has not been requested.
	//
	// Populated by the system when a graceful deletion is requested.
	// Read-only.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
	// +optional
	DeletionTimestamp *Time `json:"deletionTimestamp,omitempty" protobuf:"bytes,9,opt,name=deletionTimestamp"`

	// Number of seconds allowed for this object to gracefully terminate before
	// it will be removed from the system. Only set when deletionTimestamp is also set.
	// May only be shortened.
	// Read-only.
	// +optional
	DeletionGracePeriodSeconds *int64 `json:"deletionGracePeriodSeconds,omitempty" protobuf:"varint,10,opt,name=deletionGracePeriodSeconds"`

	// Map of string keys and values that can be used to organize and categorize
	// (scope and select) objects. May match selectors of replication controllers
	// and services.
	// More info: http://kubernetes.io/docs/user-guide/labels
	// +optional
	Labels map[string]string `json:"labels,omitempty" protobuf:"bytes,11,rep,name=labels"`

	// Annotations is an unstructured key value map stored with a resource that may be
	// set by external tools to store and retrieve arbitrary metadata. They are not
	// queryable and should be preserved when modifying objects.
	// More info: http://kubernetes.io/docs/user-guide/annotations
	// +optional
	Annotations map[string]string `json:"annotations,omitempty" protobuf:"bytes,12,rep,name=annotations"`

	// Must be empty before the object is deleted from the registry. Each entry
	// is an identifier for the responsible component that will remove the entry
	// from the list. If the deletionTimestamp of the object is non-nil, entries
	// in this list can only be removed.
	// Finalizers may be processed and removed in any order.  Order is NOT enforced
	// because it introduces significant risk of stuck finalizers.
	// finalizers is a shared field, any actor with permission can reorder it.
	// If the finalizer list is processed in order, then this can lead to a situation
	// in which the component responsible for the first finalizer in the list is
	// waiting for a signal (field value, external system, or other) produced by a
	// component responsible for a finalizer later in the list, resulting in a deadlock.
	// Without enforced ordering finalizers are free to order amongst themselves and
	// are not vulnerable to ordering changes in the list.
	// +optional
	// +patchStrategy=merge
	Finalizers []string `json:"finalizers,omitempty" patchStrategy:"merge" protobuf:"bytes,14,rep,name=finalizers"`

	// The name of the cluster which the object belongs to.
	// This is used to distinguish resources with same name and namespace in different clusters.
	// This field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.
	// +optional
	ClusterName string `json:"clusterName,omitempty" protobuf:"bytes,15,opt,name=clusterName"`
}

ObjectMeta is metadata that all persisted resources must have, which includes all objects users must create.

type PerRPCCredentials

type PerRPCCredentials interface {
	// GetRequestMetadata gets the current request metadata, refreshing
	// tokens if required. This should be called by the transport layer on
	// each request, and the data should be populated in headers or other
	// context. If a status code is returned, it will be used as the status
	// for the RPC. uri is the URI of the entry point for the request.
	// When supported by the underlying implementation, ctx can be used for
	// timeout and cancellation. Additionally, RequestInfo data will be
	// available via ctx to this call.
	// TODO(zhaoq): Define the set of the qualified keys instead of leaving
	// it as an arbitrary string.
	GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error)
	// RequireTransportSecurity indicates whether the credentials requires
	// transport security.
	RequireTransportSecurity() bool
}

PerRPCCredentials defines the common interface for the credentials which need to attach security information to every RPC (e.g., oauth2). This is the interface used by gRPC - should be implemented by all TokenSource to allow use with gRPC.

type PerRPCCredentialsFromTokenSource

type PerRPCCredentialsFromTokenSource struct {
	TokenSource
}

func (*PerRPCCredentialsFromTokenSource) GetRequestMetadata

func (s *PerRPCCredentialsFromTokenSource) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error)

func (*PerRPCCredentialsFromTokenSource) RequireTransportSecurity

func (s *PerRPCCredentialsFromTokenSource) RequireTransportSecurity() bool

type PortListener

type PortListener struct {
	Name string `json:"name,omitempty"`

	// Port number - by default listens on the public address.
	Port int32 `json:"port,omitempty"`

	// Address address (ex :8080). This is the requested address.
	//
	// BTS, SOCKS, HTTP_PROXY and IPTABLES have default ports and bindings, don't
	// need to be configured here.
	Address string `json:"address,omitempty"`

	// Port can have multiple protocols:
	// If missing or other value, this is a dedicated port, specific to a single
	// destination.
	// Gateway API defines HTTP, HTTPS, TCP, TLS, UDP
	// HBone Extensions are SNI, SOCKS5, HBONE, HBONEC, H2C
	Protocol string `json:"protocol,omitempty"`

	// ForwardTo where to forward the proxied connections.
	// Used for accepting on a dedicated port. Will be set as MeshCluster in
	// the stream, can be mesh node.
	// host:port format.
	ForwardTo string `json:"forwardTo,omitempty"`

	// Internal state.
	NetListener net.Listener `json:-`
}

PortListener represents the configuration for a real port listener. uGate has a set of special listeners that multiplex requests: - socks5 dest - iptables original dst ( may be combined with DNS interception ) - NAT dst address - SNI for TLS - :host header for HTTP - ALPN - after TLS handshake

Multiplexed channels do an additional lookup to find the listener based on the channel address.

func (*PortListener) Accept

func (l *PortListener) Accept() (net.Conn, error)

func (*PortListener) Addr

func (l *PortListener) Addr() net.Addr

func (*PortListener) Close

func (l *PortListener) Close() error

func (*PortListener) GetPort

func (l *PortListener) GetPort() int32

type Project

type Project struct {
	SSHKeys string `json:"sshKeys"`
}

type RESTRequest

type RESTRequest struct {
	Method    string
	Namespace string
	Kind      string
	Name      string

	Body []byte

	// If set, will be added at the end (must include ?). For example ?watch=0
	Query string
}

RESTRequest is a REST or K8S style request. Will be used with a Dest.

It is based on/inspired from kelseyhightower/konfig - which uses the 'raw' K8S protocol to avoid a big dependency. Google, K8S and many other APIs have a raw representation and don't require complex client libraries and depdencies. No code generation or protos are used - raw JSON in []byte is used, caller can handle marshalling.

Close to K8S raw REST client - but without the builder style.

func (*RESTRequest) HttpRequest

func (kr *RESTRequest) HttpRequest(ctx context.Context, d *Dest) *http.Request

type STS

type STS struct {
	// contains filtered or unexported fields
}

STS provides token exchanges (RFC8694).

The secure token is the K8S or other IDP token with a special audience, the result is a 'federated access token' for GCP or a regular JWT for other token exchange servers.

For GKE and GCP - the special values will be used.

See https://cloud.google.com/iam/docs/reference/sts/rest https://www.rfc-editor.org/rfc/rfc6749 - basic oauth2 https://www.rfc-editor.org/rfc/rfc8693.html https://www.ietf.org/archive/id/draft-richer-oauth-json-request-00.html

func NewFederatedTokenSource

func NewFederatedTokenSource(kr *STSAuthConfig) *STS

NewFederatedTokenSource returns federated tokens - google access tokens associated with the federated (k8s) identity. Can be used in some but not all APIs - in particular MeshCA requires this token.

https://cloud.google.com/iam/docs/reference/sts/rest/v1/TopLevel/token

If GSA is set, will also delegate to a Google account.

func (*STS) GetToken

func (s *STS) GetToken(ctx context.Context, aud string) (string, error)

func (*STS) TokenGSA

func (s *STS) TokenGSA(ctx context.Context, federatedToken string, audience string) (string, error)

Exchange a federated token equivalent with the k8s JWT with the ASM p4SA. TODO: can be used with any GSA, if the permission to call generateAccessToken is granted. This is a good way to get access tokens for a GSA using the KSA, similar with TokenRequest in the other direction.

May return an WorkloadID token with aud or access token.

https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects/-/serviceAccounts/generateAccessToken

constructFederatedTokenRequest returns an HTTP request for access token.

Example of an access token request:

POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/service-<GCP project number>@gcp-sa-meshdataplane.iam.gserviceaccount.com:generateAccessToken Content-Type: application/json Authorization: Bearer <federated token>

{
 "Delegates": [],
 "Scope": [
     https://www.googleapis.com/auth/cloud-platform
 ],
}

This requires permission to impersonate:

gcloud iam service-accounts add-iam-policy-binding \
 GSA_NAME@GSA_PROJECT_ID.iam.gserviceaccount.com \
 --role=roles/iam.workloadIdentityUser \
 --member="serviceAccount:WORKLOAD_IDENTITY_POOL[K8S_NAMESPACE/KSA_NAME]"

This can also be used with user access tokens, if user has

roles/iam.serviceAccountTokenCreator (for iam.serviceAccounts.getOpenIdToken)

The p4sa is auto-setup for all authenticated users in ASM.

type STSAuthConfig

type STSAuthConfig struct {
	// TokenSource returns 'source' tokens - with special audience that allows
	// them to be exchanged.
	//
	// For GKE - the audience should be PROJECT.svc.id.goog.
	// Can be a file source when running in K8S, if the token is mounted.
	TokenSource TokenSource

	// AudienceSource to use when getting tokens from TokenSource.
	// On GKE: fleet_project_name.svc.id.goog
	//
	// Will be used in the identitynamespace param as well as 'audience' in TokenRequest calls.
	// If missing - can be extracted from the token.
	AudienceSource string

	// GKE Dest address.
	// https://container.googleapis.com/v1/projects/%s/locations/%s/clusters/%s
	// It is also the iss field in the token.
	//
	// By default, it will be populated the first time a token is requested.
	ClusterAddress string

	// Endpoint for the STS exchange - takes a IDP JWT and gets back a
	// federated access token.
	//
	// If empty, defaults to google: "https://sts.googleapis.com/v1/token"
	STSEndpoint string

	// Scope to use in the STS exchange.
	// Defaults to google: "https://www.googleapis.com/auth/cloud-platform"
	Scope string

	// GSA is a Google service account that allows the federated identity to impersonate it ( use ).
	// If not set, the STS will only return access tokens in GCP.
	// If set, the federated token will be exchanged with an ID or access token.
	//
	// The gsa must grant the KSA (kubernetes service account) or source account
	// permission to act as the GSA.
	//
	//	In ASM, a pre-setup account with permissions to stackdriver and control plane is
	// "service-" + projectNumber + "@gcp-sa-meshdataplane.iam.gserviceaccount.com"
	//
	// REQUIRES for regular service account:
	//
	//	gcloud iam service-accounts add-iam-policy-binding \
	//			--role roles/iam.workloadIdentityUser \
	//			--member "serviceAccount:${CONFIG_PROJECT_ID}.svc.id.goog[${WORKLOAD_NAMESPACE}/default]" \
	//			k8s-${WORKLOAD_NAMESPACE}@${PROJECT_ID}.iam.gserviceaccount.com
	GSA string

	// If true, the token source returns access tokens directly.
	// This will just impersonate.
	GCPDelegate bool

	// UseAccessToken forces return of access tokens for google, even if 'aud' is set
	// Access tokens are returned by default for googleapis.com audiences.
	UseAccessToken bool
}

STSAuthConfig contains the settings for getting tokens using K8S or other federated tokens. Common usage is with a GKE cluster, with either mounted or JWT tokens from TokenRequest.

The mounted tokens MUST use PROJECT_ID.svc.id.goog as audience.

type Secret

type Secret struct {
	ObjectMeta
	Data map[string][]byte `json:"data"`
}

type StaticTokenSource

type StaticTokenSource struct {
	Token string
}

func (*StaticTokenSource) GetToken

type Store

type Store interface {
	// Get an object blob by name
	Get(name string) ([]byte, error)

	// Save a blob by name.
	Set(conf string, data []byte) error

	// List the configs starting with a prefix, of a given type.
	List(name string, tp string) ([]string, error)
}

Interface for very simple storage abstraction.

Can have a simple in-memory, fs implementation, as well as K8S, XDS or database backends.

type Subscription

type Subscription struct {
	// Endpoint is the URL to send the Web Push message to. Comes from the
	// endpoint field of the PushSubscription.
	Endpoint string

	// Key is the client's public key. From the getKey("p256dh") or keys.p256dh field.
	Key []byte

	// Auth is a value used by the client to validate the encryption. From the
	// keys.auth field.
	// The encrypted aes128gcm will have 16 bytes authentication tag derived from this.
	// This is the pre-shared authentication secret.
	Auth []byte

	// Used by the UA to receive messages, as PUSH promises
	Location string
}

Subscription holds the useful values from a PushSubscription object acquired from the browser.

https://w3c.github.io/push-api/

Returned as result of /subscribe

func SubscriptionFromJSON

func SubscriptionFromJSON(b []byte) (*Subscription, error)

SubscriptionFromJSON is a convenience function that takes a JSON encoded PushSubscription object acquired from the browser and returns a pointer to a node.

type Time

type Time struct {
	time.Time `protobuf:"-"`
}

Time is a wrapper around time.Time which supports correct marshaling to YAML and JSON. Wrappers are provided for many of the factory methods that the time package offers.

+protobuf.options.marshal=false +protobuf.as=Timestamp +protobuf.options.(gogoproto.goproto_stringer)=false

func (Time) MarshalJSON

func (t Time) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

func (*Time) UnmarshalJSON

func (t *Time) UnmarshalJSON(b []byte) error

UnmarshalJSON implements the json.Unmarshaller interface.

type Token

type Token struct {
	// TODO: use JWT - with separate mapping for access tokens.
	Token  string
	Expiry time.Time
}

Token is a subset of oauth2.Token, to avoid a dep and keep it minimal and WASM-friendly.

type TokenCache

type TokenCache struct {
	TokenSource TokenSource

	// DefaultExpiration of tokens - 45 min if not set.
	// TokenSource doesn't deal with expiration, in almost all cases 1h retry is ok.
	DefaultExpiration time.Duration
	// contains filtered or unexported fields
}

func (*TokenCache) Token

func (c *TokenCache) Token(ctx context.Context, aud string) (string, error)

type TokenResponse

type TokenResponse struct {
	// REQUIRED. The security token issued by the authorization server
	// in response to the token exchange request.
	AccessToken string `json:"access_token"`

	// REQUIRED. An identifier, representation of the issued security token.
	IssuedTokenType string `json:"issued_token_type"`

	// REQUIRED. A case-insensitive value specifying the method of using the access
	// token issued. It provides the client with information about how to utilize the
	// access token to access protected resources.
	TokenType string `json:"token_type"`

	// RECOMMENDED. The validity lifetime, in seconds, of the token issued by the
	// authorization server.
	ExpiresIn int64 `json:"expires_in"`

	// OPTIONAL, if the Scope of the issued security token is identical to the
	// Scope requested by the client; otherwise, REQUIRED.
	Scope string `json:"scope"`

	// OPTIONAL. A refresh token will typically not be issued when the exchange is
	// of one temporary credential (the subject_token) for a different temporary
	// credential (the issued token) for use in some other context.
	RefreshToken string `json:"refresh_token"`
}

TokenResponse stores all attributes sent as JSON in a successful STS response. These attributes are defined in RFC8693 2.2.1 Also RFC6749 5.1

type TokenSource

type TokenSource interface {
	// GetToken for a given audience.
	GetToken(context.Context, string) (string, error)
}

TokenSource is a common interface for anything returning Bearer or other kind of tokens.

type TokenSourceFunc

type TokenSourceFunc func(context.Context, string) (string, error)

func (TokenSourceFunc) GetToken

func (f TokenSourceFunc) GetToken(ctx context.Context, aud string) (string, error)

type TrustConfig

type TrustConfig struct {

	// Example: https://foobar.auth0.com
	// Example: 1234567-compute@developer.gserviceaccount.com (for tokens signed by a GSA)
	// In GKE, format is https://container.googleapis.com/v1/projects/$PROJECT/locations/$LOCATION/clusters/$CLUSTER
	// and the discovery doc is relative (i.e. standard).
	// The keys typically are $ISS/jwks - but OIDC document should be loaded.
	//
	// Must match the Issuer in the JWT token.
	// As 'converged' auth, this is also used to represent SSH or TLS CAs.
	Issuer string `json:"issuer,omitempty"`

	// URL of the provider's public key set to validate signature of the
	// JWT. See [OpenID Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata).
	//
	// Optional if the key set document can either (a) be retrieved from
	// [OpenID
	// Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html) of
	// the issuer or (b) inferred from the email domain of the issuer (e.g. a
	// Google service account).
	//
	// Example: `https://www.googleapis.com/oauth2/v1/certs`
	//
	//
	// Note: Only one of jwks_uri and jwks should be used. jwks_uri will be ignored if it does.
	JwksUri string `json:"jwks_uri,omitempty"`

	// JSON Web Key Set of public keys to validate signature of the JWT.
	// See https://auth0.com/docs/jwks.
	//
	// Note: In Istio, only one of jwks_uri and jwks should be used. jwks_uri
	// will be ignored if Jwks is present - but it doesn't seem right.
	//
	// TODO: mutating webhook to populate this field, controller JOB to rotate
	Jwks string `protobuf:"bytes,10,opt,name=jwks,proto3" json:"jwks,omitempty"`

	// PEM provides the set of public keys or certificates in-line.
	//
	// Not recommended - use pem_location instead so it can be reloaded, unless the trust config is reloaded itself.
	//
	// Extension to Istio JwtRule - specify the public key as PEM. This may include multiple
	// public keys or certificates. This will be populated by a mutating webhook and updated
	// by a job.
	PEM string `json:"pem,omitempty"`

	// Location of a PEM file providing the public keys or certificates of the trusted source.
	// Directory or URL. If provided, will be reloaded periodically or based on expiration time.
	PEMLocation string `json:"pem_location,omitempty"`

	// Extension to Isio JwtRule - cached subset of the OIDC discovery document
	OIDC *OIDCDiscDoc `json:"oidc,omitempty"`

	// Not stored - the actual keys or verifiers for this issuer.
	Key interface{} `json:-"`

	// KeysById is populated from the Jwks config or PEM
	KeysByKid map[string]interface{} `json:-`
	// contains filtered or unexported fields
}

Configure the settings for one trusted identity provider. This is primarily used for server side authenticating clients, but may also be used for clients authenticating servers - it defines what is trusted to provided identities.

Extended from Istio JWTRule - but unified with certificate providers.

type TypeMeta

type TypeMeta struct {
	// Kind is a string value representing the REST resource this object represents.
	// Servers may infer this from the endpoint the client submits requests to.
	// Cannot be updated.
	// In CamelCase.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
	// +optional
	Kind string `json:"kind,omitempty" protobuf:"bytes,1,opt,name=kind"`

	// APIVersion defines the versioned schema of this representation of an object.
	// Servers should convert recognized schemas to the latest internal value, and
	// may reject unrecognized values.
	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
	// +optional
	APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt,name=apiVersion"`
}

TypeMeta describes an individual object in an API response or request with strings representing the type of the object and its API schema version. Structures that are versioned or persisted should inline TypeMeta.

+k8s:deepcopy-gen=false

type UID

type UID string

UID is a type that holds unique WorkloadID values, including UUIDs. Because we don't ONLY use UUIDs, this is an alias to string. Being a type captures intent and helps make sure that UIDs and names do not get conflated.

type WebpushEncryption

type WebpushEncryption struct {
	// Full body of the encrypted message, including header (salt, server pub)
	// Format:
	// 16 B Salt
	// 4B rs {0,0, 16, 0} - 4k
	// 1B WorkloadID-Size {65}
	// 65B SendPublicKey
	// Up to 4k encrypted text - with 0x02 appended at the end before encryption
	// Wasted: 7 const.
	// Overhead: 16 salt, 16 sig, 64 pub. Total: 103 (64+32+7)
	Ciphertext []byte

	// 16B For encryption: must be a random generated by sender.
	Salt []byte

	// Temp EC key for encryption, 65B
	SendPublic []byte

	// UA Public bytes - from subscription
	UAPublic []byte

	// Only used for encrypt
	SendPrivate []byte
	// Only used for decrypt
	UAPrivate []byte

	// Auth - from subscription
	Auth []byte
	// contains filtered or unexported fields
}

WebpushEncryption stores the source and result of encrypting a message. The ciphertext is the actual encrypted message, while the salt and server public key are required to be sent to the client so that the message can be decrypted.

func NewWebpushDecryption

func NewWebpushDecryption(uapriv string, uapub, auth []byte) *WebpushEncryption

NewWebpushDecryption creates a context for decrypting message by a UA.

func NewWebpushEncryption

func NewWebpushEncryption(uapub, auth []byte) *WebpushEncryption

NewWebpushEncryption creates a new encryption context for sending, based on the subscription pub key and auth.

func (*WebpushEncryption) Decrypt

func (er *WebpushEncryption) Decrypt(cypher []byte) ([]byte, error)

func (*WebpushEncryption) Encrypt

func (er *WebpushEncryption) Encrypt(plaintext []byte) ([]byte, error)

Encrypt a message such that it can be sent using the Web Push protocol.

RFC8030 - message RFC8291 - encryption

Directories

Path Synopsis
cmd module
pkg
mdb
oidc Module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL