syntax = "proto3";

package spiffe.broker;
option go_package = "github.com/spiffe/go-spiffe/v2/exp/proto/spiffe/broker;broker";

import "google/protobuf/any.proto";

service API {
    /////////////////////////////////////////////////////////////////////////
    // X509-SVID Profile
    /////////////////////////////////////////////////////////////////////////

    // Fetch X.509-SVIDs for all SPIFFE identities the referenced workload is
    // entitled to, as well as related information like trust bundles. As this
    // information changes, subsequent messages will be streamed from the server.
    rpc SubscribeToX509SVID(SubscribeToX509SVIDRequest) returns (stream SubscribeToX509SVIDResponse);

    // Fetch trust bundles of the referenced workload. Useful in situations that
    // only need to validate SVIDs without obtaining an SVID for themself. As this
    // information changes, subsequent messages will be streamed from the server.
    rpc SubscribeToX509Bundles(SubscribeToX509BundlesRequest) returns (stream SubscribeToX509BundlesResponse);

    /////////////////////////////////////////////////////////////////////////
    // JWT-SVID Profile
    /////////////////////////////////////////////////////////////////////////

    // Fetch JWT-SVIDs for all SPIFFE identities the referenced workload is
    // entitled to, for the requested audience. If an optional SPIFFE ID is
    // requested, only the JWT-SVID for that SPIFFE ID is returned.
    rpc FetchJWTSVID(FetchJWTSVIDRequest) returns (FetchJWTSVIDResponse);

    // Fetches the JWT bundles, formatted as JWKS documents, keyed by the
    // SPIFFE ID of the trust domain. As this information changes, subsequent
    // messages will be streamed from the server.
    rpc SubscribeToJWTBundles(SubscribeToJWTBundlesRequest) returns (stream SubscribeToJWTBundlesResponse);
}

// The WorkloadReference message represents a single reference to a workload.
// The reference field contains one of the standard reference types or
// a vendor-specific extension type.
message WorkloadReference {
    // Required. The reference to the workload.
    google.protobuf.Any reference = 1;
}

// The WorkloadPIDReference message conveys a process id reference of a workload
// running in the same environment.
message WorkloadPIDReference {
    // Required. The process id of the workload. MUST be a positive integer.
    // For workloads running inside container runtimes that maintain a separate
    // sandbox (e.g. the `pause` container in containerd or CRI-O), this MUST
    // be the PID of the workload's own process, not the sandbox PID.
    int32 pid = 1;
}

// The KubernetesObjectType message identifies the type of a Kubernetes object
// by its plural name and API group. This avoids ambiguity between plurals that
// happen to contain dots (e.g., the plural `myresource.example` in the `com`
// group vs. `myresource` in the `example.com` group) that arises when the
// `<plural>.<group>` shorthand is parsed as a single string.
message KubernetesObjectType {
    // Required. The plural name of the Kubernetes resource, as registered with
    // the Kubernetes API server. For example, `pods`, `deployments`, or the
    // plural form declared by a `CustomResourceDefinition`.
    string plural = 1;

    // Required. The API group of the Kubernetes resource. For non-core
    // resources this is the API group name (e.g., `apps`, `example.com`).
    // For core resources this field MUST be set to the literal string `core`.
    string group = 2;
}

// The KubernetesObjectKey message identifies a specific Kubernetes object
// within its type by `namespace` and `name`.
message KubernetesObjectKey {
    // Optional. The namespace of the referenced Kubernetes object. MUST be set
    // for namespaced resources. MUST be empty when the resource is
    // cluster-scoped.
    string namespace = 1;

    // Required. The name of the referenced Kubernetes object.
    string name = 2;
}

// The KubernetesObjectReference message conveys a reference to an arbitrary
// Kubernetes object (built-in or custom) by which a workload is identified for
// the purpose of SVID issuance. The referenced object MUST exist and be accessible
// at the time of the request.
//
// The mapping from a Kubernetes object to a SPIFFE ID is implementation-defined;
// this specification does not mandate a particular SPIFFE ID format.
message KubernetesObjectReference {
    // Required. The type of the referenced Kubernetes object.
    KubernetesObjectType type = 1;

    // Optional. The namespaced name of the referenced Kubernetes object.
    // At least one of `key` or `uid` MUST be specified.
    KubernetesObjectKey key = 2;

    // Optional. The UID of the referenced Kubernetes object. MUST be a valid
    // UUID string as assigned by Kubernetes. At least one of `key` or `uid`
    // MUST be specified. When both `key` and `uid` are specified, the server
    // MUST verify that the object resolved by `key` has the specified UID at
    // the time of issuing the SVIDs and MUST return an error otherwise.
    string uid = 3;
}

// The SubscribeToX509SVIDRequest message conveys parameters for requesting an X.509-SVID.
message SubscribeToX509SVIDRequest {
    // Required. The reference identifying the workload.
    WorkloadReference reference = 1;
}

// The SubscribeToX509SVIDResponse message carries X.509-SVIDs and related information,
// including a list of bundles the workload may use for federating with foreign
// trust domains.
message SubscribeToX509SVIDResponse {
    // Required. A list of X509SVID messages, each of which includes a single
    // X.509-SVID, its private key, and the bundle for the trust domain.
    repeated X509SVID svids = 1;

    // Optional. ASN.1 DER encoded (not PEM) certificate revocation lists.
    repeated bytes crl = 2;

    // Optional. CA certificate bundles belonging to foreign trust domains that
    // the workload should trust, keyed by the SPIFFE ID of the foreign trust
    // domain. Bundles are ASN.1 DER encoded (not PEM).
    map<string, bytes> federated_bundles = 3;
}

// The X509SVID message carries a single SVID and all associated information,
// including the X.509 bundle for the trust domain.
message X509SVID {
    // Required. The SPIFFE ID of the SVID in this entry
    string spiffe_id = 1;

    // Required. ASN.1 DER encoded (not PEM) certificate chain. MAY include
    // intermediates, the leaf certificate (or SVID itself) MUST come first.
    bytes x509_svid = 2;

    // Required. ASN.1 DER encoded (not PEM) PKCS#8 private key. MUST be unencrypted.
    bytes x509_svid_key = 3;

    // Required. ASN.1 DER encoded (not PEM) X.509 bundle for the trust domain.
    bytes bundle = 4;

    // Optional. An operator-specified string used to provide guidance on how this
    // identity should be used by a broker or workload when more than one SVID is
    // returned. For example, `internal` and `external` to indicate an SVID for
    // internal or external use, respectively.
    string hint = 5;
}

// The SubscribeToX509BundlesRequest message conveys parameters for requesting X.509
// bundles.
message SubscribeToX509BundlesRequest {
    // Required. The reference identifying the workload.
    WorkloadReference reference = 1;
}

// The SubscribeToX509BundlesResponse message carries a map of trust bundles the workload
// should trust.
message SubscribeToX509BundlesResponse {
    // Optional. ASN.1 DER encoded (not PEM) certificate revocation lists.
    repeated bytes crl = 1;

    // Required. CA certificate bundles belonging to trust domains that the
    // workload should trust, keyed by the SPIFFE ID of the trust domain.
    // Bundles are ASN.1 DER encoded (not PEM).
    map<string, bytes> bundles = 2;
}

// The FetchJWTSVIDRequest message conveys parameters for requesting JWT-SVIDs.
message FetchJWTSVIDRequest {
    // Required. The reference identifying the workload.
    WorkloadReference reference = 1;

    // Required. The audience(s) the workload intends to authenticate against.
    repeated string audience = 2;

    // Optional. The requested SPIFFE ID for the JWT-SVID. If unset, all
    // JWT-SVIDs to which the workload is entitled are requested.
    string spiffe_id = 3;
}

// The FetchJWTSVIDResponse message conveys JWT-SVIDs.
message FetchJWTSVIDResponse {
    // Required. The list of returned JWT-SVIDs.
    repeated JWTSVID svids = 1;
}

// The JWTSVID message carries the JWT-SVID token and associated metadata.
message JWTSVID {
    // Required. The SPIFFE ID of the JWT-SVID.
    string spiffe_id = 1;

    // Required. Encoded JWT using JWS Compact Serialization.
    string svid = 2;

    // Optional. An operator-specified string used to provide guidance on how this
    // identity should be used by a workload when more than one SVID is returned.
    // For example, `internal` and `external` to indicate an SVID for internal or
    // external use, respectively.
    string hint = 3;
}

// The SubscribeToJWTBundlesRequest message conveys parameters for requesting JWT bundles.
message SubscribeToJWTBundlesRequest {
    // Required. The reference identifying the workload.
    WorkloadReference reference = 1;
}

// The SubscribeToJWTBundlesResponse message conveys JWT bundles.
message SubscribeToJWTBundlesResponse {
    // Required. JWK encoded JWT bundles, keyed by the SPIFFE ID of the trust
    // domain.
    map<string, bytes> bundles = 1;
}