mirror of
https://github.com/holos-run/holos.git
synced 2026-03-19 08:44:58 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d0dae8742 | ||
|
|
61b4b5bd17 | ||
|
|
0060740b76 | ||
|
|
bf8a4af579 | ||
|
|
dc057fe39d | ||
|
|
9877ab131a |
@@ -6,9 +6,10 @@ package holos
|
||||
// clusterName is the value of the --cluster-name flag, the cluster currently being manged / rendered.
|
||||
clusterName: string | *#ClusterName
|
||||
|
||||
extensionProviderMap: [Name=_]: {
|
||||
name: Name
|
||||
}
|
||||
// for extAuthzHttp extension providers
|
||||
extensionProviderMap: [Name=_]: #ExtAuthzProxy & {name: Name}
|
||||
// for other extension providers like zipkin
|
||||
extensionProviderExtraMap: [Name=_]: {name: Name}
|
||||
|
||||
config: {
|
||||
accessLogEncoding: string | *"JSON"
|
||||
@@ -21,7 +22,10 @@ package holos
|
||||
enablePrometheusMerge: false | *true
|
||||
rootNamespace: string | *"istio-system"
|
||||
trustDomain: string | *"cluster.local"
|
||||
extensionProviders: [for x in extensionProviderMap {x}]
|
||||
extensionProviders: [
|
||||
for x in extensionProviderMap {x},
|
||||
for y in extensionProviderExtraMap {y},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,10 @@ spec: components: HelmChartList: [
|
||||
}
|
||||
}
|
||||
apiObjectMap: OBJECTS.apiObjectMap
|
||||
// Auth Proxy
|
||||
apiObjectMap: _IngressAuthProxy.Deployment.apiObjectMap
|
||||
// Auth Policy
|
||||
apiObjectMap: _IngressAuthProxy.Policy.apiObjectMap
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package holos
|
||||
|
||||
// Ingress Gateway default auth proxy
|
||||
let Provider = _IngressAuthProxy.AuthProxySpec.provider
|
||||
let Service = _IngressAuthProxy.service
|
||||
#MeshConfig: extensionProviderMap: (Provider): envoyExtAuthzHttp: service: Service
|
||||
|
||||
// Istio meshconfig
|
||||
// TODO: Generate per-project extauthz providers.
|
||||
_MeshConfig: (#MeshConfig & {projects: _Projects}).config
|
||||
|
||||
@@ -1,5 +1,281 @@
|
||||
package holos
|
||||
|
||||
import "encoding/yaml"
|
||||
|
||||
#InstancePrefix: "prod-mesh"
|
||||
|
||||
#IstioVersion: "1.21.0"
|
||||
|
||||
// The ingress gateway auth proxy is used by multiple cue instances.
|
||||
// AUTHPROXY configures one oauth2-proxy deployment for each host in each stage of a project. Multiple deployments per stage are used to narrow down the cookie domain.
|
||||
_IngressAuthProxy: {
|
||||
Name: "authproxy"
|
||||
Namespace: "istio-ingress"
|
||||
service: "\(Name).\(Namespace).svc.cluster.local"
|
||||
AuthProxySpec: #AuthProxySpec & #Platform.authproxy
|
||||
|
||||
Domains: [DOMAIN=string]: {name: DOMAIN}
|
||||
Domains: (#Platform.org.domain): _
|
||||
Domains: "\(#ClusterName).\(#Platform.org.domain)": _
|
||||
|
||||
let Metadata = {
|
||||
name: string
|
||||
namespace: Namespace
|
||||
labels: "app.kubernetes.io/name": name
|
||||
labels: "app.kubernetes.io/part-of": "istio-ingressgateway"
|
||||
...
|
||||
}
|
||||
|
||||
let ProxyMetadata = Metadata & {name: Name}
|
||||
let RedisMetadata = Metadata & {name: Name + "-redis"}
|
||||
|
||||
// Deployment represents the oauth2-proxy deployment
|
||||
Deployment: #APIObjects & {
|
||||
apiObjects: {
|
||||
// oauth2-proxy
|
||||
ExternalSecret: (Name): metadata: ProxyMetadata
|
||||
// Place the ID token in a header that does not conflict with the Authorization header.
|
||||
// Refer to: https://github.com/oauth2-proxy/oauth2-proxy/issues/1877#issuecomment-1364033723
|
||||
ConfigMap: (Name): {
|
||||
metadata: ProxyMetadata
|
||||
data: "config.yaml": yaml.Marshal(AuthProxyConfig)
|
||||
let AuthProxyConfig = {
|
||||
injectResponseHeaders: [{
|
||||
name: "x-oidc-id-token"
|
||||
values: [{claim: "id_token"}]
|
||||
}]
|
||||
providers: [{
|
||||
id: "Holos Platform"
|
||||
name: "Holos Platform"
|
||||
provider: "oidc"
|
||||
scope: "openid profile email groups offline_access urn:zitadel:iam:org:domain:primary:\(AuthProxySpec.orgDomain)"
|
||||
clientID: AuthProxySpec.clientID
|
||||
clientSecretFile: "/dev/null"
|
||||
code_challenge_method: "S256"
|
||||
loginURLParameters: [{
|
||||
default: ["force"]
|
||||
name: "approval_prompt"
|
||||
}]
|
||||
oidcConfig: {
|
||||
issuerURL: AuthProxySpec.issuer
|
||||
audienceClaims: ["aud"]
|
||||
emailClaim: "email"
|
||||
groupsClaim: "groups"
|
||||
userIDClaim: "sub"
|
||||
}
|
||||
}]
|
||||
server: BindAddress: ":4180"
|
||||
upstreamConfig: upstreams: [{
|
||||
id: "static://200"
|
||||
path: "/"
|
||||
static: true
|
||||
staticCode: 200
|
||||
}]
|
||||
}
|
||||
}
|
||||
Deployment: (Name): #Deployment & {
|
||||
metadata: ProxyMetadata
|
||||
|
||||
spec: {
|
||||
replicas: 1
|
||||
selector: matchLabels: ProxyMetadata.labels
|
||||
template: {
|
||||
metadata: labels: ProxyMetadata.labels
|
||||
metadata: labels: #IstioSidecar
|
||||
spec: {
|
||||
securityContext: seccompProfile: type: "RuntimeDefault"
|
||||
containers: [{
|
||||
image: "quay.io/oauth2-proxy/oauth2-proxy:v7.6.0"
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
name: "oauth2-proxy"
|
||||
volumeMounts: [{
|
||||
name: "config"
|
||||
mountPath: "/config"
|
||||
readOnly: true
|
||||
}]
|
||||
args: [
|
||||
// callback url is proxy prefix + /callback
|
||||
"--proxy-prefix=" + AuthProxySpec.proxyPrefix,
|
||||
"--email-domain=*",
|
||||
"--session-store-type=redis",
|
||||
"--redis-connection-url=redis://\(RedisMetadata.name):6379",
|
||||
"--cookie-refresh=12h",
|
||||
"--cookie-expire=2160h",
|
||||
"--cookie-secure=true",
|
||||
"--cookie-name=__Secure-\(#ClusterName)-ingress-\(Name)",
|
||||
"--cookie-samesite=lax",
|
||||
for domain in Domains {"--cookie-domain=.\(domain.name)"},
|
||||
for domain in Domains {"--cookie-domain=\(domain.name)"},
|
||||
for domain in Domains {"--whitelist-domain=.\(domain.name)"},
|
||||
for domain in Domains {"--whitelist-domain=\(domain.name)"},
|
||||
"--cookie-csrf-per-request=true",
|
||||
"--cookie-csrf-expire=120s",
|
||||
// will skip authentication for OPTIONS requests
|
||||
"--skip-auth-preflight=true",
|
||||
"--real-client-ip-header=X-Forwarded-For",
|
||||
"--skip-provider-button=true",
|
||||
"--auth-logging",
|
||||
"--alpha-config=/config/config.yaml",
|
||||
]
|
||||
env: [{
|
||||
name: "OAUTH2_PROXY_COOKIE_SECRET"
|
||||
// echo '{"cookiesecret":"'$(LC_ALL=C tr -dc "[:alpha:]" </dev/random | tr '[:upper:]' '[:lower:]' | head -c 32)'"}' | holos create secret -n istio-ingress --append-hash=false --data-stdin authproxy
|
||||
valueFrom: secretKeyRef: {
|
||||
key: "cookiesecret"
|
||||
name: Name
|
||||
}
|
||||
}]
|
||||
ports: [{
|
||||
containerPort: 4180
|
||||
protocol: "TCP"
|
||||
}]
|
||||
securityContext: {
|
||||
seccompProfile: type: "RuntimeDefault"
|
||||
allowPrivilegeEscalation: false
|
||||
runAsNonRoot: true
|
||||
runAsUser: 8192
|
||||
runAsGroup: 8192
|
||||
capabilities: drop: ["ALL"]
|
||||
}
|
||||
}]
|
||||
volumes: [{name: "config", configMap: name: Name}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Service: (Name): #Service & {
|
||||
metadata: ProxyMetadata
|
||||
spec: selector: ProxyMetadata.labels
|
||||
spec: ports: [
|
||||
{port: 4180, targetPort: 4180, protocol: "TCP", name: "http"},
|
||||
]
|
||||
}
|
||||
VirtualService: (Name): #VirtualService & {
|
||||
metadata: ProxyMetadata
|
||||
spec: hosts: ["*"]
|
||||
spec: gateways: ["istio-ingress/default"]
|
||||
spec: http: [{
|
||||
match: [{uri: prefix: AuthProxySpec.proxyPrefix}]
|
||||
route: [{
|
||||
destination: host: Name
|
||||
destination: port: number: 4180
|
||||
}]
|
||||
}]
|
||||
}
|
||||
|
||||
// redis
|
||||
ConfigMap: (RedisMetadata.name): {
|
||||
metadata: RedisMetadata
|
||||
data: "redis.conf": """
|
||||
maxmemory 128mb
|
||||
maxmemory-policy allkeys-lru
|
||||
"""
|
||||
}
|
||||
Deployment: (RedisMetadata.name): {
|
||||
metadata: RedisMetadata
|
||||
spec: {
|
||||
selector: matchLabels: RedisMetadata.labels
|
||||
template: {
|
||||
metadata: labels: RedisMetadata.labels
|
||||
metadata: labels: #IstioSidecar
|
||||
spec: securityContext: seccompProfile: type: "RuntimeDefault"
|
||||
spec: {
|
||||
containers: [{
|
||||
command: [
|
||||
"redis-server",
|
||||
"/redis-master/redis.conf",
|
||||
]
|
||||
env: [{
|
||||
name: "MASTER"
|
||||
value: "true"
|
||||
}]
|
||||
image: "quay.io/holos/redis:7.2.4"
|
||||
livenessProbe: {
|
||||
initialDelaySeconds: 15
|
||||
tcpSocket: port: "redis"
|
||||
}
|
||||
name: "redis"
|
||||
ports: [{
|
||||
containerPort: 6379
|
||||
name: "redis"
|
||||
}]
|
||||
readinessProbe: {
|
||||
exec: command: [
|
||||
"redis-cli",
|
||||
"ping",
|
||||
]
|
||||
initialDelaySeconds: 5
|
||||
}
|
||||
resources: limits: cpu: "0.5"
|
||||
securityContext: {
|
||||
seccompProfile: type: "RuntimeDefault"
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities: drop: ["ALL"]
|
||||
runAsNonRoot: true
|
||||
runAsUser: 999
|
||||
runAsGroup: 999
|
||||
}
|
||||
volumeMounts: [{
|
||||
mountPath: "/redis-master-data"
|
||||
name: "data"
|
||||
}, {
|
||||
mountPath: "/redis-master"
|
||||
name: "config"
|
||||
}]
|
||||
}]
|
||||
volumes: [{
|
||||
emptyDir: {}
|
||||
name: "data"
|
||||
}, {
|
||||
configMap: name: RedisMetadata.name
|
||||
name: "config"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Service: (RedisMetadata.name): #Service & {
|
||||
metadata: RedisMetadata
|
||||
spec: selector: RedisMetadata.labels
|
||||
spec: type: "ClusterIP"
|
||||
spec: ports: [{
|
||||
name: "redis"
|
||||
port: 6379
|
||||
protocol: "TCP"
|
||||
targetPort: 6379
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Policy represents the AuthorizationPolicy and RequestAuthentication policy
|
||||
Policy: #APIObjects & {
|
||||
apiObjects: {
|
||||
RequestAuthentication: (Name): #RequestAuthentication & {
|
||||
metadata: Metadata & {name: Name}
|
||||
spec: jwtRules: [{
|
||||
audiences: ["\(AuthProxySpec.projectID)"]
|
||||
forwardOriginalToken: true
|
||||
fromHeaders: [{name: AuthProxySpec.idTokenHeader}]
|
||||
issuer: AuthProxySpec.issuer
|
||||
}]
|
||||
spec: selector: matchLabels: istio: "ingressgateway"
|
||||
}
|
||||
AuthorizationPolicy: "\(Name)-custom": {
|
||||
metadata: Metadata & {name: "\(Name)-custom"}
|
||||
spec: {
|
||||
action: "CUSTOM"
|
||||
provider: name: AuthProxySpec.provider
|
||||
// bypass the external authorizer when the id token is already in the request.
|
||||
// the RequestAuthentication rule will verify the token.
|
||||
rules: [{when: [
|
||||
{key: "request.headers[\(AuthProxySpec.idTokenHeader)]", notValues: ["*"]},
|
||||
// TODO: Define a way for hosts to be excluded.
|
||||
{key: "request.headers[host]", notValues: [AuthProxySpec.issuerHost]},
|
||||
]}]
|
||||
selector: matchLabels: istio: "ingressgateway"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,23 @@ package holos
|
||||
#Project: authProxyOrgDomain: "openinfrastructure.co"
|
||||
|
||||
_Projects: #Projects & {
|
||||
// The platform project is required and where platform services reside. ArgoCD, Grafana, Prometheus, etc...
|
||||
platform: {
|
||||
resourceId: 257713952794870157
|
||||
clusters: k1: _
|
||||
clusters: k2: _
|
||||
stages: dev: authProxyClientID: "260887327029658738@holos_platform"
|
||||
stages: prod: authProxyClientID: "260887404288738416@holos_platform"
|
||||
// Services hosted in the platform project
|
||||
hosts: argocd: _
|
||||
hosts: grafana: _
|
||||
hosts: prometheus: _
|
||||
}
|
||||
|
||||
holos: {
|
||||
resourceId: 260446255245690199
|
||||
clusters: {
|
||||
k1: _
|
||||
k2: _
|
||||
}
|
||||
clusters: k1: _
|
||||
clusters: k2: _
|
||||
stages: dev: authProxyClientID: "260505543108527218@holos"
|
||||
stages: prod: authProxyClientID: "260506079325128023@holos"
|
||||
environments: {
|
||||
|
||||
@@ -4,7 +4,7 @@ package holos
|
||||
projects: _
|
||||
clusterName: _
|
||||
|
||||
extensionProviderMap: {
|
||||
extensionProviderExtraMap: {
|
||||
"cluster-trace": {
|
||||
zipkin: {
|
||||
maxTagLength: 56
|
||||
|
||||
@@ -75,24 +75,32 @@ import "encoding/yaml"
|
||||
}
|
||||
|
||||
// Manage auth-proxy in each stage
|
||||
"\(stage.slug)-authproxy": #KubernetesObjects & {
|
||||
apiObjectMap: (#APIObjects & {
|
||||
apiObjects: (AUTHPROXY & {stage: Stage, project: Project, servers: GatewayServers[stage.name]}).apiObjects
|
||||
}).apiObjectMap
|
||||
if project.features.authproxy.enabled {
|
||||
"\(stage.slug)-authproxy": #KubernetesObjects & {
|
||||
apiObjectMap: (#APIObjects & {
|
||||
apiObjects: (AUTHPROXY & {stage: Stage, project: Project, servers: GatewayServers[stage.name]}).apiObjects
|
||||
}).apiObjectMap
|
||||
}
|
||||
|
||||
for Env in project.environments if Env.stage == stage.name {
|
||||
"\(Env.slug)-authpolicy": #KubernetesObjects & {
|
||||
// Manage auth policy in each env
|
||||
apiObjectMap: (#APIObjects & {
|
||||
apiObjects: (AUTHPOLICY & {env: Env, project: Project, servers: GatewayServers[stage.name]}).apiObjects
|
||||
}).apiObjectMap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Manage httpbin in each environment
|
||||
for Env in project.environments if Env.stage == stage.name {
|
||||
"\(Env.slug)-httpbin": #KubernetesObjects & {
|
||||
let Project = project
|
||||
apiObjectMap: (#APIObjects & {
|
||||
apiObjects: (HTTPBIN & {env: Env, project: Project}).apiObjects
|
||||
}).apiObjectMap
|
||||
|
||||
// Manage auth policy in each env
|
||||
apiObjectMap: (#APIObjects & {
|
||||
apiObjects: (AUTHPOLICY & {env: Env, project: Project, servers: GatewayServers[stage.name]}).apiObjects
|
||||
}).apiObjectMap
|
||||
if project.features.httpbin.enabled {
|
||||
for Env in project.environments if Env.stage == stage.name {
|
||||
"\(Env.slug)-httpbin": #KubernetesObjects & {
|
||||
let Project = project
|
||||
apiObjectMap: (#APIObjects & {
|
||||
apiObjects: (HTTPBIN & {env: Env, project: Project}).apiObjects
|
||||
}).apiObjectMap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -194,6 +202,14 @@ let AUTHPROXY = {
|
||||
let Project = project
|
||||
let Stage = stage
|
||||
|
||||
let AuthProxySpec = #AuthProxySpec & {
|
||||
namespace: stage.namespace
|
||||
projectID: project.resourceId
|
||||
clientID: stage.authProxyClientID
|
||||
orgDomain: project.authProxyOrgDomain
|
||||
provider: stage.extAuthzProviderName
|
||||
}
|
||||
|
||||
let Metadata = {
|
||||
name: Name
|
||||
namespace: stage.namespace
|
||||
@@ -224,15 +240,15 @@ let AUTHPROXY = {
|
||||
data: "config.yaml": yaml.Marshal(AuthProxyConfig)
|
||||
let AuthProxyConfig = {
|
||||
injectResponseHeaders: [{
|
||||
name: "x-oidc-id-token"
|
||||
name: AuthProxySpec.idTokenHeader
|
||||
values: [{claim: "id_token"}]
|
||||
}]
|
||||
providers: [{
|
||||
id: "Holos Platform"
|
||||
name: "Holos Platform"
|
||||
provider: "oidc"
|
||||
scope: "openid profile email groups offline_access urn:zitadel:iam:org:domain:primary:\(project.authProxyOrgDomain)"
|
||||
clientID: stage.authProxyClientID
|
||||
scope: "openid profile email groups offline_access urn:zitadel:iam:org:domain:primary:\(AuthProxySpec.orgDomain)"
|
||||
clientID: AuthProxySpec.clientID
|
||||
clientSecretFile: "/dev/null"
|
||||
code_challenge_method: "S256"
|
||||
loginURLParameters: [{
|
||||
@@ -240,7 +256,7 @@ let AUTHPROXY = {
|
||||
name: "approval_prompt"
|
||||
}]
|
||||
oidcConfig: {
|
||||
issuerURL: project.authProxyIssuer
|
||||
issuerURL: AuthProxySpec.issuer
|
||||
audienceClaims: ["aud"]
|
||||
emailClaim: "email"
|
||||
groupsClaim: "groups"
|
||||
@@ -285,7 +301,7 @@ let AUTHPROXY = {
|
||||
}]
|
||||
args: [
|
||||
// callback url is proxy prefix + /callback
|
||||
"--proxy-prefix=" + project.authProxyPrefix,
|
||||
"--proxy-prefix=" + AuthProxySpec.proxyPrefix,
|
||||
"--email-domain=*",
|
||||
"--session-store-type=redis",
|
||||
"--redis-connection-url=redis://\(RedisMetadata.name):6379",
|
||||
@@ -345,7 +361,7 @@ let AUTHPROXY = {
|
||||
spec: hosts: ["*"]
|
||||
spec: gateways: ["istio-ingress/\(stage.slug)"]
|
||||
spec: http: [{
|
||||
match: [{uri: prefix: project.authProxyPrefix}]
|
||||
match: [{uri: prefix: AuthProxySpec.proxyPrefix}]
|
||||
route: [{
|
||||
destination: host: Name
|
||||
destination: port: number: 4180
|
||||
@@ -447,6 +463,14 @@ let AUTHPOLICY = {
|
||||
let stage = project.stages[env.stage]
|
||||
let Env = env
|
||||
|
||||
let AuthProxySpec = #AuthProxySpec & {
|
||||
namespace: stage.namespace
|
||||
projectID: project.resourceId
|
||||
clientID: stage.authProxyClientID
|
||||
orgDomain: project.authProxyOrgDomain
|
||||
provider: stage.extAuthzProviderName
|
||||
}
|
||||
|
||||
let Metadata = {
|
||||
name: string
|
||||
namespace: env.namespace
|
||||
@@ -469,16 +493,16 @@ let AUTHPOLICY = {
|
||||
for host in Hosts {host.name},
|
||||
for host in Hosts {host.name + ":*"},
|
||||
]
|
||||
let MatchLabels = {"security.holos.run/authproxy": stage.extAuthzProviderName}
|
||||
let MatchLabels = {"security.holos.run/authproxy": AuthProxySpec.provider}
|
||||
|
||||
apiObjects: {
|
||||
RequestAuthentication: (Name): #RequestAuthentication & {
|
||||
metadata: Metadata & {name: Name}
|
||||
spec: jwtRules: [{
|
||||
audiences: [stage.authProxyClientID]
|
||||
audiences: [AuthProxySpec.clientID]
|
||||
forwardOriginalToken: true
|
||||
fromHeaders: [{name: "x-oidc-id-token"}]
|
||||
issuer: project.authProxyIssuer
|
||||
fromHeaders: [{name: AuthProxySpec.idTokenHeader}]
|
||||
issuer: AuthProxySpec.issuer
|
||||
}]
|
||||
spec: selector: matchLabels: MatchLabels
|
||||
}
|
||||
@@ -487,8 +511,19 @@ let AUTHPOLICY = {
|
||||
spec: {
|
||||
action: "CUSTOM"
|
||||
// send the request to the auth proxy
|
||||
provider: name: stage.extAuthzProviderName
|
||||
rules: [{to: [{operation: hosts: HostList}]}]
|
||||
provider: name: AuthProxySpec.provider
|
||||
rules: [{
|
||||
to: [{operation: hosts: HostList}]
|
||||
when: [
|
||||
{
|
||||
key: "request.headers[\(AuthProxySpec.idTokenHeader)]"
|
||||
notValues: ["*"]
|
||||
},
|
||||
{
|
||||
key: "request.headers[host]"
|
||||
notValues: [AuthProxySpec.issuerHost]
|
||||
},
|
||||
]}]
|
||||
selector: matchLabels: MatchLabels
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,9 @@ import "strings"
|
||||
// #Projects is a map of all the projects in the platform.
|
||||
#Projects: [Name=_]: #Project & {name: Name}
|
||||
|
||||
// The platform project is required and where platform services reside. ArgoCD, Grafana, Prometheus, etc...
|
||||
#Projects: platform: _
|
||||
|
||||
#Project: {
|
||||
name: string
|
||||
// resourceId is the zitadel project Resource ID
|
||||
@@ -23,8 +26,6 @@ import "strings"
|
||||
}
|
||||
domain: string | *#Platform.org.domain
|
||||
|
||||
// authProxyPrefix is the path routed to the ext auth proxy.
|
||||
authProxyPrefix: string | *"/holos/oidc"
|
||||
// authProxyOrgDomain is the primary org domain for zitadel.
|
||||
authProxyOrgDomain: string | *#Platform.org.domain
|
||||
// authProxyIssuer is the issuer url
|
||||
@@ -60,6 +61,8 @@ import "strings"
|
||||
|
||||
// features is YAGNI maybe?
|
||||
features: [Name=string]: #Feature & {name: Name}
|
||||
features: authproxy: _
|
||||
features: httpbin: _
|
||||
}
|
||||
|
||||
// #Cluster defines a cluster
|
||||
@@ -124,7 +127,7 @@ import "strings"
|
||||
#Feature: {
|
||||
name: string
|
||||
description: string
|
||||
enabled: *true | false
|
||||
enabled: true | *false
|
||||
}
|
||||
|
||||
#ProjectTemplate: {
|
||||
|
||||
@@ -112,7 +112,7 @@ _apiVersion: "holos.run/v1alpha1"
|
||||
_name: string
|
||||
metadata: {
|
||||
name: _name
|
||||
namespace: #TargetNamespace
|
||||
namespace: string | *#TargetNamespace
|
||||
}
|
||||
spec: {
|
||||
refreshInterval: string | *"1h"
|
||||
@@ -225,6 +225,32 @@ _apiVersion: "holos.run/v1alpha1"
|
||||
services: [ID=_]: {
|
||||
name: string & ID
|
||||
}
|
||||
// authproxy configures the auth proxy attached to the default ingress gateway in the istio-ingress namespace.
|
||||
authproxy: #AuthProxySpec & {
|
||||
namespace: "istio-ingress"
|
||||
provider: "ingressauth"
|
||||
}
|
||||
}
|
||||
|
||||
#AuthProxySpec: {
|
||||
// projectID is the zitadel project resource id.
|
||||
projectID: number
|
||||
// clientID is the zitadel application client id.
|
||||
clientID: string
|
||||
// namespace is the namespace
|
||||
namespace: string
|
||||
// provider is the istio extension provider name in the mesh config.
|
||||
provider: string
|
||||
// orgDomain is the zitadel organization domain for logins.
|
||||
orgDomain: string | *#Platform.org.domain
|
||||
// issuerHost is the Host: header value of the oidc issuer
|
||||
issuerHost: string | *"login.\(#Platform.org.domain)"
|
||||
// issuer is the oidc identity provider issuer url
|
||||
issuer: string | *"https://\(issuerHost)"
|
||||
// path is the oauth2-proxy --proxy-prefix value. The default callback url is the Host: value with a path of /holos/oidc/callback
|
||||
proxyPrefix: string | *"/holos/authproxy/\(namespace)"
|
||||
// idTokenHeader represents the header where the id token is placed
|
||||
idTokenHeader: string | *"x-oidc-id-token"
|
||||
}
|
||||
|
||||
// ManagedNamespace is a namespace to manage across all clusters in the holos platform.
|
||||
|
||||
@@ -1 +1 @@
|
||||
5
|
||||
7
|
||||
|
||||
Reference in New Issue
Block a user