Skip to content

Commit 02ead8d

Browse files
committed
feat(docs): adds docs for hardened mode and addresses feedback
1 parent e22203d commit 02ead8d

21 files changed

+278
-104
lines changed

.github/workflows/sphinx-python-dependency-build-checks.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,5 @@ jobs:
5151
run: |
5252
set -ex
5353
make install \
54-
PIPOPTS="--no-binary :all:" \
54+
PIPOPTS="--no-binary :all: --only-binary html5lib" \
5555
|| ( cat .sphinx/venv/pip_install.log && exit 1 )

docs/.custom_wordlist.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Leave a blank line at the end of this file to support concatenation
2+
ambient's
23
backend
34
backends
5+
CIDR
46
Charmcraft
57
config
68
Consol
@@ -20,6 +22,7 @@ http
2022
https
2123
html
2224
instantiation
25+
IPs
2326
Istio
2427
Istio's
2528
Intersphinx
@@ -63,8 +66,11 @@ toctree
6366
txt
6467
uncommenting
6568
ui
69+
ztunnel
6670
utils
6771
VMs
72+
waypoint
73+
waypoints
6874
Waypoint
6975
WCAG
7076
Wordpress
-32.7 KB
Binary file not shown.

docs/conf.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@
2525
#
2626
# TODO: Update with the official name of your project or product
2727

28-
project = "Service Mesh"
28+
project = "Canonical Service Mesh"
2929
author = "Canonical Ltd."
3030

3131

3232
# Sidebar documentation title; best kept reasonably short
33-
html_title = project + " Documentation"
33+
html_title = "Documentation"
3434

3535

3636
# Copyright string; shown at the bottom of the page
@@ -184,16 +184,20 @@
184184

185185
linkcheck_ignore = [
186186
"http://127.0.0.1:8000",
187-
"https://github.com/canonical/ACME/*"
187+
"https://github.com/canonical/ACME/*",
188+
r"https://matrix\.to/.*",
188189
]
189190

190191

191192
# A regex list of URLs where anchors are ignored by 'make linkcheck'
192193

193-
linkcheck_anchors_ignore_for_url = [r"https://github\.com/.*"]
194+
linkcheck_anchors_ignore_for_url = [
195+
r"https://github\.com/.*",
196+
r"https://istio\.io/.*",
197+
]
194198

195199
# give linkcheck multiple tries on failure
196-
# linkcheck_timeout = 30
200+
linkcheck_timeout = 60
197201
linkcheck_retries = 3
198202

199203
########################
@@ -236,6 +240,7 @@
236240
"sphinx_last_updated_by_git",
237241
"sphinx.ext.intersphinx",
238242
"sphinx_sitemap",
243+
"sphinxcontrib.mermaid",
239244
]
240245

241246
# Excludes files or directories from processing
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Compatibility with Cilium CNI
2+
3+
`Cilium` is an `eBPF` based CNI which includes some intelligent kernel level traffic re-routing using `eBPF` programs. This traffic re-routing can potentially interfere with `Istio ambient's` mesh features.
4+
5+
```{note}
6+
The complete compatibility documentation between Cilium and Istio can be found [here](https://docs.cilium.io/en/stable/network/servicemesh/istio/). This documentation only covers certain gotchas that is not explicitly clear from the mentioned doc.
7+
```
8+
9+
By default `Cilium` is designed to be the exclusive CNI which wont allow the Istio CNI plugin to be successfully deployed. Hence it is important to make sure `Cilium` is configured to allow external CNI plugins.
10+
11+
Assuming `Cilium` allows `Istio's` CNI plugin, the major compatibility issue between them is caused by the fact that `Cilium` load balances traffic at the kernel level. This means traffic directed at Kubernetes Services are re-routed by Cilium directly to the destination Pod.
12+
13+
`Istio ambient`, in order to apply policies and encrypt traffic, routes the traffic via its `ztunnel` component either using `iptables` or higher level `eBPF` programs. Since the `Cilium's` re-routing applies at the kernel level, the traffic is never routed through the `ztunnel` at the source. This prevents `Istio ambient` from successfully encrypting the traffic or applying the `AuthorizationPolicies`. This issue can be solved by the `socketLB.hostNamespaceOnly: true` setting in `Cilium` which basically instructs `Cilium` to limit load balancing to the host network namespace. Hence the K8s internal traffic flows through the normal network stack allowing `Istio ambient` to function normally.
14+
15+
An important gotcha that is not mentioned in the `Cilium` documentation is the fact that, even when `socketLB.hostNamespaceOnly` is set to be `false`, the destination `ztunnel` will successfully capture the traffic to the destination pod and might apply L4 policies directed at the pod. This might give the impression that service mesh is working successfully and will mask the fact the traffic between the source pod and destination pod is not encrypted by Istio ambient (if `mTLS` mode is set to be `PERMISSIVE`).
16+
17+
The recommended configuration to successfully use Charmed Istio with Canonical Kubernetes with the `Cilium` CNI can be found in [this](../how-to/use-charmed-istio-with-canonical-kubernetes.md) how-to documentation.

docs/explanation/hardened-mode.md

Lines changed: 88 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,91 @@
11
# Hardened Mode
22

3-
```{note}
4-
This page is planned but not yet written
3+
In a zero-trust network, no service is trusted by default and every request must be explicitly authorized before it is allowed through. Hardened mode brings this principle to the service mesh by enforcing a deny-by-default security posture: all inbound traffic to services on the mesh is denied unless an authorization policy explicitly allows it.
4+
5+
## Why hardened mode is needed
6+
7+
By default, Istio ambient only enforces authorization on workloads that are explicitly targeted by an `AuthorizationPolicy`. Any workload without a policy applied to it will accept all inbound traffic. This means:
8+
9+
* if a service on the mesh has no policy targeting it, the **ztunnel** will allow any traffic through to that service
10+
* when [`auto-allow-waypoint-policy`](https://charmhub.io/istio-k8s/configurations#auto-allow-waypoint-policy) is enabled (the default), if no policy targets a service at the **waypoint**, any service can reach it
11+
12+
In practice, this leaves services that haven't been explicitly locked down wide open. Hardened mode closes this gap by ensuring that all traffic is denied by default across the entire mesh.
13+
14+
## How it works
15+
16+
Enabling hardened mode on the [`istio-k8s`](https://charmhub.io/istio-k8s) charm creates two global **allow-nothing** `AuthorizationPolicies`.
17+
18+
### Why allow-nothing instead of deny-all?
19+
20+
The distinction matters because of how Istio ambient [evaluates authorization policies](https://istio.io/latest/docs/concepts/security/#authorization-policy-precedence). Istio ambient processes policies in this order: `CUSTOM` then `DENY` then `ALLOW`. A `DENY` policy always takes precedence. Once traffic matches a `DENY` rule, it is rejected regardless of any `ALLOW` policies. This means a global `DENY`-all policy would lock down the cluster permanently with no way to override it.
21+
22+
An allow-nothing policy works differently. It is an `ALLOW` policy with an empty rule set, meaning it matches no traffic. However, its presence activates Istio ambient's [implicit deny behavior](https://istio.io/latest/docs/concepts/security/#allow-nothing-deny-all-and-allow-all-policy): once at least one `ALLOW` policy exists for a workload, any traffic that does not match an `ALLOW` rule is denied. Other `ALLOW` policies can then selectively open up the specific traffic that should be permitted. This gives us a secure default that can still be overridden by explicit allow rules.
23+
24+
### ztunnel allow-nothing policy
25+
26+
An `AuthorizationPolicy` with an empty spec acts as a global allow-nothing policy. This ensures that any traffic not matched by an explicit `ALLOW` policy is denied at the ztunnel layer:
27+
28+
```yaml
29+
apiVersion: security.istio.io/v1
30+
kind: AuthorizationPolicy
31+
metadata:
32+
name: istio-k8s-istio-system-policy-global-allow-nothing-ztunnel
33+
namespace: istio-system
34+
spec: {}
35+
```
36+
37+
### Waypoint allow-nothing policy
38+
39+
A similar policy targets the `istio-waypoint` `GatewayClass`, locking down all traffic that passes through the waypoint:
40+
41+
```yaml
42+
apiVersion: security.istio.io/v1
43+
kind: AuthorizationPolicy
44+
metadata:
45+
name: istio-k8s-istio-system-policy-global-allow-nothing-waypoint
46+
namespace: istio-system
47+
spec:
48+
targetRefs:
49+
- kind: GatewayClass
50+
group: gateway.networking.k8s.io
51+
name: istio-waypoint
52+
```
53+
54+
Together, these two policies ensure that no service-to-service communication is allowed anywhere on the mesh unless an explicit `ALLOW` policy exists for it. See [Traffic authorization](./traffic-authorization.md) for how these allow policies are created by the beacon charm.
55+
56+
## Effect on ingress traffic
57+
58+
Hardened mode also blocks external traffic from reaching the Istio ingress gateway, since the global deny applies to all inbound traffic including traffic arriving from a `LoadBalancer`.
59+
60+
To handle this, the [`istio-ingress-k8s`](https://charmhub.io/istio-ingress-k8s) charm automatically creates an `ALLOW` policy that permits external traffic to reach the gateway:
61+
62+
```yaml
63+
apiVersion: security.istio.io/v1
64+
kind: AuthorizationPolicy
65+
metadata:
66+
name: istio-ingress-k8s-istio-system-external-traffic
67+
namespace: istio-system
68+
spec:
69+
action: ALLOW
70+
targetRefs:
71+
- kind: Gateway
72+
group: gateway.networking.k8s.io
73+
name: istio-ingress-k8s
74+
rules:
75+
- from:
76+
- source:
77+
ipBlocks:
78+
- "0.0.0.0/0"
579
```
6-
```{note}
7-
This should be written for general service mesh charms, not just istio
8-
```
80+
81+
By default, this allows traffic from any source IP (`0.0.0.0/0`) because an ingressed application is typically meant to be publicly accessible. To restrict access to specific source IPs or CIDR ranges, use the `external-traffic-policy-cidrs` configuration option on [`istio-ingress-k8s`](https://charmhub.io/istio-ingress-k8s/configurations).
82+
83+
## Enabling hardened mode
84+
85+
To enable hardened mode, set the `hardened-mode` configuration option on the `istio-k8s` charm:
86+
87+
```bash
88+
juju config istio-k8s hardened-mode=true
89+
```
90+
91+
For all available configuration options, see the [istio-k8s](https://charmhub.io/istio-k8s/configurations) and [istio-ingress-k8s](https://charmhub.io/istio-ingress-k8s/configurations) charm configuration pages.

docs/explanation/index.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,10 @@
33
These documents provide an explanation of key topics and concepts of the Canonical Service Mesh.
44

55
```{toctree}
6-
:maxdepth: 1
6+
:maxdepth: 2
77
88
service-mesh
99
istio
10-
hardened-mode
11-
managed-mode
12-
traffic-authorization
1310
service-mesh-in-coordinated-worker-charms
1411
```
1512

docs/explanation/istio.md

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Istio
1+
# Charmed Istio Ambient
22

33
[Istio](https://istio.io) is an implementation of a [service mesh](./service-mesh.md). It helps you:
44

@@ -8,39 +8,23 @@
88

99
Although Kubernetes natively provides facilities to do some of this, Istio implements richer solutions. For example, Istio's [AuthorizationPolicy](https://istio.io/latest/docs/reference/config/security/authorization-policy/) object implements fine-grained authorization controls, and Istio can automate mutual TLS between all applications on the mesh.
1010

11-
## Charmed Istio
12-
13-
Charmed Istio is an opinionated deployment of Istio using [Juju](http://juju.is/). The goals of Charmed Istio are to:
11+
Charmed Istio ambient is an opinionated deployment of Istio's [Ambient Mode](https://istio.io/latest/docs/ambient/overview/) using [Juju](http://juju.is/). The goals of Charmed Istio ambient are to:
1412

1513
* provide a simple-to-deploy, easy-to-manage Istio experience, giving most of Istio's benefits without a need for advanced Istio experience
1614
* be customizable for power users, so users can build advanced use cases on top of the standard Charmed Istio base
1715

18-
Charmed Istio uses Istio's [Ambient Mode](https://istio.io/latest/docs/ambient/overview/) and is implemented through the following charms:
16+
It is implemented through the following charms:
1917

2018
* [istio-k8s](https://charmhub.io/istio-k8s): for deploying and managing the Istio control panel, such as the Istio daemon and its resources
2119
* [istio-beacon-k8s](https://charmhub.io/istio-beacon-k8s/): for integrating a Juju model and its applications to Charmed Istio, as well as deploying an Istio Waypoint for those applications
2220
* [istio-ingress-k8s](https://charmhub.io/istio-ingress-k8s): for deploying and managing an Istio ingress gateway
2321

24-
Core elements of Charmed Istio include:
25-
26-
* automatic mTLS communication between all applications on the service mesh
27-
* default security features through [hardened mode](./hardened-mode.md)
28-
* easy, fine-grained, app-to-app authorization control through [managed mode](./managed-mode.md)
29-
30-
## Using Istio with Cilium CNI
22+
```{toctree}
23+
:maxdepth: 1
24+
:hidden:
3125
32-
`Cilium` is an `eBPF` based CNI which includes some intelligent kernel level traffic re-routing using `eBPF` programs. This traffic re-routing can potentially interfere with `Istio's` mesh features.
33-
34-
```{note}
35-
The complete compatibility documentation between Cilium and Istio can be found [here](https://docs.cilium.io/en/stable/network/servicemesh/istio/). This documentation only covers certain gotchas that is not explicitly clear from the mentioned doc.
26+
hardened-mode
27+
managed-mode
28+
traffic-authorization
29+
cilium-cni-compatibility
3630
```
37-
38-
By default `Cilium` is designed to be the exclusive CNI which wont allow the Istio CNI plugin to be successfully deployed. Hence it is important to make sure `Cilium` is configured to allow external CNI plugins.
39-
40-
Assuming `Cilium` allows `Istio's` CNI plugin, the major compatibility issue between them is caused by the fact that `Cilium` load balances traffic at the kernel level. This means traffic directed at Kubernetes Services are re-routed by Cilium directly to the destination Pod.
41-
42-
`Istio`, in order to apply policies and encrypt traffic, routes the traffic via its `ztunnel` component either using `iptables` or higher level `eBPF` programs. Since the `Cilium's` re-routing applies at the kernel level, the traffic is never routed through the `ztunnel` at the source. This prevents `Istio` from successfully encrypting the traffic or applying the `AuthorizationPolicies`. This issue can be solved by the `socketLB.hostNamespaceOnly: true` setting in `Cilium` which basically instructs `Cilium` to limit load balancing to the host network namespace. Hence the K8s internal traffic flows through the normal network stack allowing `Istio` to function normally.
43-
44-
An important gotcha that is not mentioned in the `Cilium` documentation is the fact that, even when `socketLB.hostNamespaceOnly` is set to be `false`, the destination `ztunnel` will successfully capture the traffic to the destination pod and might apply L4 policies directed at the pod. This might give the impression that service mesh is working successfully and will mask the fact the traffic between the source pod and destination pod is not encrypted by Istio (if `mTLS` mode is set to be `PERMISSIVE`).
45-
46-
The recommended configuration to successfully use Charmed Istio with Canonical Kubernetes with the `Cilium` CNI can be found in [this](../how-to/use-charmed-istio-with-canonical-kubernetes.md) how-to documentation.

docs/explanation/managed-mode.md

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,59 @@
11
# Managed Mode
22

3-
All Charmed Service Mesh Beacon charms (for example, [istio-beacon-k8s](https://charmhub.io/istio-beacon-k8s/)) include optional [management of authorization policies between applications](../explanation/traffic-authorization.md). When enabled, the beacon charms will automatically generate policies that allow related applications to communicate with each other [as specified by the charm authors via the `ServiceMeshConsumer` library](../how-to/add-mesh-support-to-your-charm.md).
3+
Managed mode refers to a set of configuration options that together control how authorization policies are automatically created and enforced on the mesh. When fully enabled, the beacon charm automatically generates `AuthorizationPolicies` based on what charm authors define via the [`ServiceMeshConsumer` library](../how-to/add-mesh-support-to-your-charm.md), so administrators do not need to create policies manually.
44

5-
If managed mode is disabled, policy creation is left up to the administrator to do manually.
5+
## manage-authorization-policies
6+
7+
The [`manage-authorization-policies`](https://charmhub.io/istio-beacon-k8s/configure#manage-authorization-policies) option on the beacon charm is the core of managed mode. When set to `true` (the default), the beacon charm reads the policies defined by each charm via the `ServiceMeshConsumer` library and creates the corresponding Istio `AuthorizationPolicies` automatically.
8+
9+
For example, using the [Get started with Charmed Istio ambient](../tutorial/get-started-with-the-charmed-istio-mesh.md) tutorial, the `bookinfo-details-k8s` charm defines a policy allowing `GET` requests to `/health` and `/details/*` on port `9080`. When `bookinfo-productpage-k8s` is related to `bookinfo-details-k8s` and both are on the mesh, the beacon charm creates an `AuthorizationPolicy` like the following:
10+
11+
```yaml
12+
apiVersion: security.istio.io/v1
13+
kind: AuthorizationPolicy
14+
metadata:
15+
name: istio-beacon-k8s-bookinfo-policy-bookinfo-productpage-k8s-bookinfo-bookinfo-details-k8s-ad9cfa91
16+
namespace: bookinfo
17+
labels:
18+
app.kubernetes.io/instance: istio-beacon-k8s-bookinfo
19+
kubernetes-resource-handler-scope: istio-authorization-policy
20+
spec:
21+
rules:
22+
- from:
23+
- source:
24+
principals:
25+
- cluster.local/ns/bookinfo/sa/bookinfo-productpage-k8s
26+
to:
27+
- operation:
28+
methods:
29+
- GET
30+
paths:
31+
- /health
32+
- /details/*
33+
ports:
34+
- '9080'
35+
targetRefs:
36+
- group: ''
37+
kind: Service
38+
name: bookinfo-details-k8s
39+
```
40+
41+
This policy allows `bookinfo-productpage-k8s` (identified by its service account) to make `GET` requests to the specified paths and port on `bookinfo-details-k8s`, and nothing else.
42+
43+
When `manage-authorization-policies` is set to `false`, the beacon charm will not create any authorization policies but will still perform other functions like providing a waypoint. In this case, policy creation is left to the administrator.
44+
45+
## Related configuration options
46+
47+
Managed mode works alongside two configuration options on the [`istio-k8s`](https://charmhub.io/istio-k8s) charm that affect how the automatically created policies behave:
48+
49+
### hardened-mode
50+
51+
When [hardened mode](./hardened-mode.md) is enabled, global allow-nothing policies ensure that all traffic is denied unless an explicit `ALLOW` policy exists. Without hardened mode, the policies created by managed mode only restrict traffic to workloads that are explicitly targeted. Workloads without any policy still accept all traffic. Enabling both managed mode and hardened mode together provides full zero-trust enforcement: managed mode creates the allow rules, and hardened mode ensures everything else is denied.
52+
53+
### auto-allow-waypoint-policy
54+
55+
The [`auto-allow-waypoint-policy`](https://charmhub.io/istio-k8s/configure#auto-allow-waypoint-policy) option (enabled by default) tells Istio ambient to automatically create synthetic L4 authorization policies that allow waypoints to forward traffic to their workloads. Without this, the policies created by managed mode would be evaluated at the waypoint but the traffic from the waypoint to the destination workload would be blocked at the ztunnel layer unless a separate L4 policy exists. Keeping this option enabled means administrators only need to think about the application level policies that managed mode handles.
56+
57+
## Disabling managed mode
58+
59+
All of the policy related configuration options described above can be disabled. When they are, Charmed Istio ambient hands off all authorization control to the administrator. No policies are automatically created or enforced, and all traffic management must be done manually by creating and maintaining `AuthorizationPolicies` directly.

docs/how-to/add-mesh-support-to-your-charm.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,6 @@ juju relate my-db-provider:database my-db-consumer:database
126126
juju relate my-db-provider:provide-cmr-support my-db-consumer:require-cmr-support
127127
```
128128

129-
For a more detailed tutorial using cross-model integrations, follow the [Use the Istio Mesh across different Juju models](../tutorial/use-the-istio-mesh-across-different-juju-models.md) tutorial.
129+
For a more detailed tutorial using cross-model integrations, follow the [Use Istio ambient across different Juju models](../tutorial/use-the-istio-mesh-across-different-juju-models.md) tutorial.
130130

131131
[^1]: For a detailed explanation of exactly what is generated automatically, see [Authorization Policy Creation in Istio](../explanation/traffic-authorization.md)

0 commit comments

Comments
 (0)