Skip to content

portal

Version: 0.1.0 Type: application AppVersion: 0.1.0

Portal — an admission webhook, informer-driven audit loop, and declarative NetworkPolicy analyser, with a built-in response-action engine. Successor to podwatcher-poc; AlertManager-compatible, PolicyReport-native, expr-lang rules.

Homepage: https://github.com/vilaca/portal

Maintainers

Name Email Url
Joao Vilaca joao.vilaca@relexsolutions.com

Source Code

Requirements

Kubernetes: >=1.27.0-0

Values

Key Type Default Description
affinity object {} Affinity rules applied to Portal pods. The chart adds a preferred pod anti-affinity by default — overridden when this value is non-empty.
alertmanager.url string "" AlertManager v2 alerts endpoint. Empty disables the AlertManager sink.
audit.enabled bool false
audit.leaderElection bool true Enable lease-based leader election. Informers run on every replica; only the leader dispatches actions / writes PolicyReports.
audit.resyncPeriod string "10m" Informer resync period. Watch events are the main path; resync is a safety net only.
certManager.enabled bool false Use cert-manager to provision the webhook TLS Secret. When false the binary bootstraps a self-signed CA on startup and patches the ValidatingWebhookConfiguration.caBundle itself.
certManager.issuerKind string "" Issuer kind to use when certManager.enabled. When empty an in-chart self-signed Issuer is created.
certManager.issuerName string "" Issuer name to use when certManager.enabled. When empty an in-chart self-signed Issuer is created.
extraEnv list [] Extra environment variables for the Portal container.
extraVolumeMounts list [] Extra volume mounts on the Portal container.
extraVolumes list [] Extra volumes mounted in the Portal pod.
global.failClosed bool true Whether the ValidatingWebhookConfiguration uses failurePolicy=Fail. When true, API server requests are rejected if Portal is unavailable — ≥2 replicas + PDB become mandatory. System namespaces are always excluded regardless of this flag (see templates/validatingwebhookconfiguration.yaml).
global.mode string "combined" Deployment topology. "combined" runs every enabled layer in one Deployment. "split" deploys one Deployment per layer (admission / audit / network) for independent scaling. v1 ships combined only; the split-mode templates are stubbed for forward compat.
image.pullPolicy string "IfNotPresent" Container image pull policy.
image.pullSecrets list [] Image pull secrets to attach to the ServiceAccount.
image.repository string "ghcr.io/vilaca/portal" Container image repository.
image.tag string "" Container image tag. Defaults to the chart appVersion when empty.
metrics.port int 9090 Container port the Prometheus /metrics + /healthz + /readyz listener serves on.
network.enabled bool false
nodeSelector object {} Node selector applied to Portal pods.
podDisruptionBudget.minAvailable int 1 Minimum available replicas during voluntary disruption. ≥1 is required when failClosed=true. Set to 0 to disable the PDB entirely.
podSecurityContext.fsGroup int 65532 Pod-level fsGroup. 65532 is the distroless nonroot group.
podSecurityContext.runAsNonRoot bool true Reject pods whose container security context allows root.
podSecurityContext.seccompProfile.type string "RuntimeDefault" Seccomp profile applied at pod level.
policyReport.enabled bool true Emit wgpolicyk8s.io/v1alpha2 PolicyReport / ClusterPolicyReport CRs.
rbac.actions.annotate bool false Grant patch on workload kinds so the annotate action can mutate metadata.annotations via server-side apply.
rbac.actions.evict bool false Grant create on pods/eviction so the evict action can drain pods.
rbac.actions.label bool false Grant patch on workload kinds so the label action can mutate metadata.labels via server-side apply.
rbac.actions.patchnp bool false Grant patch on networkpolicies.networking.k8s.io for the patch-NP action.
rbac.actions.revoketoken bool false Grant delete on secrets so the revoke-sa-token action can force ServiceAccount token rotation.
rbac.create bool true Create the ClusterRole + ClusterRoleBinding.
replicaCount int 2 Number of Portal replicas. 2 is the minimum for fail-closed HA; the PodDisruptionBudget keeps ≥1 healthy during rollouts so workload-namespace admission requests continue to succeed.
resources.limits.cpu string "500m" CPU limit per Portal pod.
resources.limits.memory string "256Mi" Memory limit per Portal pod.
resources.requests.cpu string "100m" CPU request per Portal pod.
resources.requests.memory string "128Mi" Memory request per Portal pod.
rules.cr bool true
rules.folderConfigMap string "" Name of an existing ConfigMap holding rule YAML files. Mounted at /etc/portal/rules and passed via --rules-folder. Empty disables folder loading.
securityContext.allowPrivilegeEscalation bool false Disallow privilege escalation.
securityContext.capabilities.drop list ["ALL"] Drop all Linux capabilities; Portal needs none.
securityContext.readOnlyRootFilesystem bool true Mount the root filesystem read-only.
securityContext.runAsGroup int 65532 Run as the distroless nonroot group.
securityContext.runAsNonRoot bool true Enforce non-root execution at container level.
securityContext.runAsUser int 65532 Run as the distroless nonroot user.
serviceAccount.annotations object {} Extra annotations on the ServiceAccount (useful for IRSA / Workload Identity).
serviceAccount.create bool true Create a ServiceAccount for Portal. Set to false to reuse an existing one.
serviceAccount.name string "" Name of the ServiceAccount. Defaults to portal.fullname.
serviceMonitor.enabled bool false Create a Prometheus Operator ServiceMonitor.
serviceMonitor.interval string "30s" Scrape interval.
serviceMonitor.labels object {} Extra labels added to the ServiceMonitor (typically the Prometheus release label for kube-prometheus-stack).
tolerations list [] Tolerations applied to Portal pods.
watchedGvks list [] Additional GVKs to start informers for, in "group/version/Kind" form. Empty group renders as "/v1/ConfigMap" etc. These extend the set computed from the audited rule corpus.
webhook.caBundle string "" Optional pre-baked caBundle (base64). When empty, Portal patches the ValidatingWebhookConfiguration at startup with its self-signed CA, or cert-manager populates it via the Certificate's caBundle injection.
webhook.enabled bool true
webhook.port int 8443 Container port the webhook TLS server listens on.
webhook.rules list [{"apiGroups":[""],"apiVersions":["v1"],"operations":["CREATE","UPDATE"],"resources":["pods"]},{"apiGroups":["apps"],"apiVersions":["v1"],"operations":["CREATE","UPDATE"],"resources":["deployments","statefulsets","daemonsets","replicasets"]},{"apiGroups":["batch"],"apiVersions":["v1"],"operations":["CREATE","UPDATE"],"resources":["jobs","cronjobs"]},{"apiGroups":["networking.k8s.io"],"apiVersions":["v1"],"operations":["CREATE","UPDATE"],"resources":["networkpolicies"]}] GVKs subject to admission. Each entry is {apiGroups, apiVersions, resources}. The system-namespace exclusion is layered on top of this via namespaceSelector.
webhook.timeoutSeconds int 5 Webhook timeoutSeconds in the ValidatingWebhookConfiguration.