Files
holos/docs/examples/project-hosts.cue
Jeff McCune ce8bc798f6 (#133) Exclude nats and provision hosts from the auth proxy
Problem:
The identity aware auth proxy attached to the default gateway is
blocking access to NATS and the Choria Provisioner cluster.

Solution:
Add configuration that causes the project hosts to get added to the
exclusion list of the AuthorizationPolicy/authproxy-custom rule.

Result:
Requests bypass the auth proxy and go straight to the backend.  The
rules look like:

    kubectl get authorizationpolicy authproxy-custom -o yaml

```yaml
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: authproxy-custom
  namespace: istio-ingress
  labels:
    app.kubernetes.io/name: authproxy-custom
    app.kubernetes.io/part-of: istio-ingressgateway
spec:
  action: CUSTOM
  provider:
    name: ingressauth
  rules:
  - to:
    - operation:
        notHosts:
        - login.ois.run
        - vault.core.ois.run
        - provision.holos.run
        - nats.holos.run
        - provision.dev.holos.run
        - nats.dev.holos.run
        - jeff.provision.dev.holos.run
        - jeff.nats.dev.holos.run
        - gary.provision.dev.holos.run
        - gary.nats.dev.holos.run
        - nate.provision.dev.holos.run
        - nate.nats.dev.holos.run
        - provision.k2.holos.run
        - nats.k2.holos.run
        - provision.dev.k2.holos.run
        - nats.dev.k2.holos.run
        - jeff.provision.dev.k2.holos.run
        - jeff.nats.dev.k2.holos.run
        - gary.provision.dev.k2.holos.run
        - gary.nats.dev.k2.holos.run
        - nate.provision.dev.k2.holos.run
        - nate.nats.dev.k2.holos.run
    when:
    - key: request.headers[x-oidc-id-token]
      notValues:
      - '*'
  selector:
    matchLabels:
      istio: ingressgateway
```
2024-04-19 06:32:11 -07:00

144 lines
3.7 KiB
CUE

package holos
import "strings"
// #ProjectHosts represents all of the hosts associated with the project
// organized for use in Certificates, Gateways, VirtualServices.
#ProjectHosts: {
project: #Project
// Hosts map key fqdn to host to reduce into structs organized by stage,
// canonical name, etc... The flat nature and long list of properties is
// intended to make it straight forward to derive another struct for Gateways,
// VirtualServices, Certificates, AuthProxy cookie domains, etc...
Hosts: {
for Env in project.environments {
for Host in project.hosts {
// Global hostname, e.g. app.holos.run
let CertInfo = (#MakeCertInfo & {
host: Host
env: Env
domain: project.domain
clusterMap: project.clusters
}).CertInfo
"\(CertInfo.fqdn)": CertInfo
// Cluster hostname, e.g. app.east1.holos.run, app.west1.holos.run
for Cluster in project.clusters {
let CertInfo = (#MakeCertInfo & {
host: Host
env: Env
domain: project.domain
cluster: Cluster.name
clusterMap: project.clusters
}).CertInfo
"\(CertInfo.fqdn)": CertInfo
}
}
}
}
}
// #MakeCertInfo provides dns info for a certificate
// Refer to: https://github.com/holos-run/holos/issues/66#issuecomment-2027562626
#MakeCertInfo: {
host: #Host
env: #Environment
domain: string
cluster: string
clusterMap: #ClusterMap
let Stage = #StageInfo & {name: env.stage, project: env.project}
let Env = env
// DNS segments from left to right.
let EnvSegments = env.envSegments
WildcardSegments: [...string]
if len(env.envSegments) > 0 {
WildcardSegments: ["*"]
}
let HostSegments = [host.name]
let StageSegments = env.stageSegments
ClusterSegments: [...string]
if cluster != _|_ {
ClusterSegments: [cluster]
}
let DomainSegments = [domain]
// Assemble the segments
let FQDN = EnvSegments + HostSegments + StageSegments + ClusterSegments + DomainSegments
let WILDCARD = WildcardSegments + HostSegments + StageSegments + ClusterSegments + DomainSegments
let CANONICAL = HostSegments + StageSegments + DomainSegments
CertInfo: #CertInfo & {
fqdn: strings.Join(FQDN, ".")
wildcard: strings.Join(WILDCARD, ".")
canonical: strings.Join(CANONICAL, ".")
project: name: Env.project
stage: #StageOrEnvRef & {
name: Stage.name
slug: Stage.slug
namespace: Stage.namespace
}
env: #StageOrEnvRef & {
name: Env.name
slug: Env.slug
namespace: Env.namespace
}
if cluster != _|_ {
// Host is valid on a single cluster.
clusters: "\(cluster)": _
}
if cluster == _|_ {
// Host is valid on all project clusters.
clusters: clusterMap
}
NoAuthorizationPolicy: host.NoAuthorizationPolicy
}
}
// #CertInfo defines the attributes associated with a fully qualfied domain name
#CertInfo: {
// fqdn is the fully qualified domain name, never a wildcard.
fqdn: string
// canonical is the canonical name this name may be an alternate name for.
canonical: string
// wildcard may replace the left most segment fqdn with a wildcard to consolidate cert dnsNames. If not a wildcad, must be fqdn
wildcard: string
// Project, stage and env attributes for mapping and collecting.
project: name: string
stage: #StageOrEnvRef
env: #StageOrEnvRef
// clusters represents the cluster names the fqdn is valid on.
clusters: #ClusterMap
// hosts are always valid on the provisioner cluster
clusters: provisioner: _
// NoAuthorizationPolicy excludes the host from the auth proxy integrated with
// the default ingress Gateway.
NoAuthorizationPolicy: true | *false
}
#ClusterMap: [Name=string]: #Cluster & {name: Name}
#StageOrEnvRef: {
name: string
slug: string
namespace: string
}