{"id":18332569,"url":"https://github.com/tigera-solutions/cc-demo-workload-security","last_synced_at":"2025-07-24T22:05:08.155Z","repository":{"id":153125791,"uuid":"575560120","full_name":"tigera-solutions/cc-demo-workload-security","owner":"tigera-solutions","description":"Demo for workload security","archived":false,"fork":false,"pushed_at":"2022-12-08T18:18:50.000Z","size":188,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-15T11:19:54.393Z","etag":null,"topics":["aws","cc","eks","regismartins","security","workshop"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tigera-solutions.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-07T19:38:35.000Z","updated_at":"2023-08-01T11:24:04.000Z","dependencies_parsed_at":null,"dependency_job_id":"e6645f8c-44ca-4b4d-9ab9-d295a8c6ee86","html_url":"https://github.com/tigera-solutions/cc-demo-workload-security","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigera-solutions%2Fcc-demo-workload-security","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigera-solutions%2Fcc-demo-workload-security/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigera-solutions%2Fcc-demo-workload-security/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tigera-solutions%2Fcc-demo-workload-security/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tigera-solutions","download_url":"https://codeload.github.com/tigera-solutions/cc-demo-workload-security/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248089395,"owners_count":21045898,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","cc","eks","regismartins","security","workshop"],"created_at":"2024-11-05T19:39:25.412Z","updated_at":"2025-04-09T18:39:23.131Z","avatar_url":"https://github.com/tigera-solutions.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Calico Cloud Demo on an EKS Cluster\n\nIn this demo, you will work with AWS EKS and Calico Cloud to learn how to design and deploy best practices to secure your Kubernetes environment. This 60-minute hands-on lab will guide you from building an EKS cluster, creating a Calico Cloud trial account and registering your EKS cluster to Calico Cloud for configuring security policies to protect your workloads. This sample environment is designed to help implement:\n\n- Security Policies for pods and namespaces.\n  - Policy tiers\n  - Security Policies\n  - Security Policy Recommender\n  - DNS Policies\n  - Ingress Policies\n- Infrastructure as a Code and Calico Cloud.\n- Customizing deployed policies.\n- Best Practices for EKS cluster.\n\n---\n\n### Create your EKS cluster\n\nCalico can be used as a CNI, or you can decide to use AWS VPC networking and have Calico only as plugin for the security policies. \n\nWe will use the second approach during the demo. Below an example on how to create a two nodes cluster with an smaller footprint, but feel free to create your EKS cluster with the parameters you prefer. Do not forget to include the region if different than the default on your account.\n\n```bash\nexport CLUSTERNAME=rm-demo\nexport REGION=ca-central-1\neksctl create cluster --name $CLUSTERNAME --version 1.21  --region $REGION --node-type m5.xlarge\n```\n\n### Connect your cluster to Calico Cloud\n\nSubscribe to the free Calico Cloud trial on the link below:\n\nhttps://www.calicocloud.io/home\n\nOnce you are able to login to Calico Cloud UI, go to the \"Managed clusters\" section, and click on the \"Connect Cluster\" button, then leave \"Amazon EKS\" selected, and give a name to your cluster, and click \"Next\". Read the cluster requirements in teh next section, and click \"Next\". Finally, copy the kubectl command you must run in order to connect your cluster to the management cluster for your Calico Cloud instance.\n\n![managed-clusters](https://user-images.githubusercontent.com/104035488/206290672-8af9c13f-314a-4752-8cb8-ff1b892484d6.png)\n\n---\n\n## Enviroment Preparation\n\n### Clone this repository\n\n```bash\ngit clone git@github.com:tigera-solutions/cc-demo-workload-security.git\n```\n\n### Decrease the time to collect flow logs\n\nBy default, flow logs are collected every 5 minutes. We will decrease that time to 15 seconds, which will increase the amount of information we must store, and while that is not recommended for production environments, it will help to speed up the time in which events are seen within Calico observability features.\n\n```bash\nkubectl patch felixconfiguration default -p '{\"spec\":{\"flowLogsFlushInterval\":\"15s\"}}'\nkubectl patch felixconfiguration default -p '{\"spec\":{\"dnsLogsFlushInterval\":\"15s\"}}'\nkubectl patch felixconfiguration default -p '{\"spec\":{\"flowLogsFileAggregationKindForAllowed\":1}}'\nkubectl patch felixconfiguration default -p '{\"spec\":{\"flowLogsFileAggregationKindForDenied\":0}}'\nkubectl patch felixconfiguration default -p '{\"spec\":{\"dnsLogsFileAggregationKind\":0}}'\n```\n\nConfigure Felix to collect TCP stats - this uses eBPF TC program and requires miniumum Kernel version of v5.3.0/v4.18.0-193. Further documentation.\n\n```bash\nkubectl patch felixconfiguration default -p '{\"spec\":{\"flowLogsCollectTcpStats\":true}}'\n```\n\n### Install demo applications\n\nDeploy the dev app stack\n\n```bash\nkubectl apply -f ./manifests/dev-app-manifest.yaml\n```\n \nDeploy the Online Boutique app stack\n\n```bash\nkubectl apply -f ./manifests/kubernetes-manifests.yaml\n```\n\n---\n\n## Access controls\n\nCalico provides methods to enable fine-grained access controls between your microservices and external databases, cloud services, APIs, and other applications that are protected behind a firewall. You can enforce controls from within the cluster using DNS egress policies, from a firewall outside the cluster using the egress gateway. Controls are applied on a fine-grained, per-pod basis.\n\n## Service Graph and Flow Visualizer\n\nConnect to Calico Cloud GUI. From the menu select `Service Graph \u003e Default`. Explore the options.\n\n![service_graph](https://user-images.githubusercontent.com/104035488/192303379-efb43faa-1e71-41f2-9c54-c9b7f0538b34.gif)\n\nConnect to Calico Cloud GUI. From the menu select `Service Graph \u003e Flow Visualizations`. Explore the options.\n\n![flow-visualization](https://user-images.githubusercontent.com/104035488/192358472-112c832f-2fd7-4294-b8cc-fec166a9b11e.gif)\n\n\n## Security Policy Tiers\n\nTiers are a hierarchical construct used to group policies and enforce higher precedence policies that cannot be circumvented by other    teams. \n\nAll Calico and Kubernetes security policies reside in tiers. You can start “thinking in tiers” by grouping your teams and types of policies within each group. The command below will create three tiers (quarantine, platform, and security):\n\n```yaml\nkubectl apply -f - \u003c\u003c-EOF   \napiVersion: projectcalico.org/v3\nkind: Tier\nmetadata:\n  name: security\nspec:\n  order: 300\n---\napiVersion: projectcalico.org/v3\nkind: Tier\nmetadata:\n  name: platform\nspec:\n  order: 400\nEOF\n```\n\nPolicies are processed in sequential order from top to bottom.\n\n![policy-processing](https://user-images.githubusercontent.com/104035488/206433417-0d186664-1514-41cc-80d2-17ed0d20a2f4.png)\n\nTwo mechanisms drive how traffic is processed across tiered policies:\n\n- Labels and selectors\n- Policy action rules\n\nFor more information about tiers, please refer to the Calico Cloud documentation [Understanding policy tiers](https://docs.calicocloud.io/get-started/tutorials/policy-tiers)\n\n\n---\n\n\n## Security Policies\n\nCalico Security Policies provide a richer set of policy capabilities than Kubernetes network policies including:  \n\n- Policies that can be applied to any kind of endpoint: pods/containers, VMs, and/or to host interfaces\n- Policies that can define rules that apply to ingress, egress, or both\n- Policy rules support:\n  - Actions: allow, deny, log, pass\n  - Source and destination match criteria:\n    - Ports: numbered, ports in a range, and Kubernetes named ports\n    - Protocols: TCP, UDP, ICMP, SCTP, UDPlite, ICMPv6, protocol numbers (1-255)\n    - HTTP attributes (if using Istio service mesh)\n    - ICMP attributes\n    - IP version (IPv4, IPv6)\n    - IP or CIDR\n    - Endpoint selectors (using label expression to select pods, VMs, host interfaces, and/or network sets)\n    - Namespace selectors\n    - Service account selectors\n\n\n\n### The Zero Trust approach\n\nA global default deny policy ensures that unwanted traffic (ingress and egress) is denied by default. Pods without policy (or incorrect policy) are not allowed traffic until appropriate network policy is defined. Although the staging policy tool will help you find incorrect and missing policy, a global deny helps mitigate against other lateral malicious attacks.\n\nBy default, all traffic is allowed between the pods in a cluster. First, let's test connectivity between application components and across application stacks. All of these tests should succeed as there are no policies in place.\n\nFirst, let's install `curl` in the loadgenerator pod for these tests.\n\n```bash\nkubectl exec -it $(kubectl get po -l app=loadgenerator -ojsonpath='{.items[0].metadata.name}') -c main -- sh -c 'apt-get update \u0026\u0026 apt install curl -y'\n```\n\na. Test connectivity between workloads within each namespace, use dev and default namespaces as example\n\n   ```bash\n   # test connectivity within dev namespace, the expected result is \"HTTP/1.1 200 OK\" \n   kubectl -n dev exec -t centos -- sh -c 'curl -m3 -sI http://nginx-svc 2\u003e/dev/null | grep -i http'\n   ```\n\n   ```bash\n   # test connectivity within default namespace in 8080 port\n   kubectl exec -it $(kubectl -n default get po -l app=frontend -ojsonpath='{.items[0].metadata.name}') \\\n   -c server -- sh -c 'nc -zv recommendationservice 8080'\n   ```\n\nb. Test connectivity across namespaces dev/centos and default/frontend.\n\n   ```bash\n   # test connectivity from dev namespace to default namespace, the expected result is \"HTTP/1.1 200 OK\"\n   kubectl -n dev exec -t centos -- sh -c 'curl -m3 -sI http://frontend.default 2\u003e/dev/null | grep -i http'\n   ```\n\nc. Test connectivity from each namespace dev and default to the Internet.\n\n   ```bash\n   # test connectivity from dev namespace to the Internet, the expected result is \"HTTP/1.1 200 OK\"\n   kubectl -n dev exec -t centos -- sh -c 'curl -m3 -sI http://www.google.com 2\u003e/dev/null | grep -i http'\n   ```\n\n   ```bash\n   # test connectivity from default namespace to the Internet, the expected result is \"HTTP/1.1 200 OK\"\n   kubectl exec -it $(kubectl get po -l app=loadgenerator -ojsonpath='{.items[0].metadata.name}') \\\n   -c main -- sh -c 'curl -m3 -sI http://www.google.com 2\u003e/dev/null | grep -i http'\n   ```\n\nWe recommend that you create a global default deny policy after you complete writing policy for the traffic that you want to allow. Use the stage policy feature to get your allowed traffic working as expected, then lock down the cluster to block unwanted traffic.\n\n1. Create a staged global default deny policy. It will shows all the traffic that would be blocked if it were converted into a deny.\n\n   ```yaml\n   kubectl apply -f - \u003c\u003c-EOF\n   apiVersion: projectcalico.org/v3\n   kind: StagedGlobalNetworkPolicy\n   metadata:\n     name: default-deny\n   spec:\n     order: 2000\n     selector: \"projectcalico.org/namespace in {'dev','default'}\"\n     types:\n     - Ingress\n     - Egress\n   EOF\n   ```\n\n   The staged policy does not affect the traffic directly but allows you to view the policy impact if it were to be enforced. You can see the deny traffic in staged policy.\n\n\n2. Create a network policy to allow the traffic shown as blocked (staged) in step 1, from the centos pod to the nginx in the same namespace.\n  \n   ```yaml\n   kubectl apply -f - \u003c\u003c-EOF   \n   apiVersion: projectcalico.org/v3\n   kind: NetworkPolicy\n   metadata:\n     name: default.centos\n     namespace: dev\n   spec:\n     tier: default\n     order: 800\n     selector: app == \"centos\"\n     egress:\n     - action: Allow\n       protocol: UDP\n       destination:\n         selector: k8s-app == \"kube-dns\"\n         namespaceSelector: kubernetes.io/metadata.name == \"kube-system\" \n         ports:\n         - '53'\n     - action: Allow\n       protocol: TCP\n       destination:\n         selector: app == \"nginx\"\n     types:\n       - Egress\n   EOF\n   ```\n\n3. Test connectivity with the policy in place.\n\n   a. The only connections between the components within namespaces dev are from centos to nginx, which should be allowed as configured by the policies.\n\n   ```bash\n   # test connectivity within dev namespace, the expected result is \"HTTP/1.1 200 OK\"\n   kubectl -n dev exec -t centos -- sh -c 'curl -m3 -sI http://nginx-svc 2\u003e/dev/null | grep -i http'\n   ```\n   \n   The connections within namespace default should be allowed as usual.\n   \n   ```bash\n   # test connectivity within default namespace in 8080 port\n   kubectl exec -it $(kubectl get po -l app=frontend -ojsonpath='{.items[0].metadata.name}') \\\n   -c server -- sh -c 'nc -zv recommendationservice 8080'\n   ``` \n\n   b. The connections across dev/centos pod and default/frontend pod should be blocked by the application policy.\n   \n   ```bash   \n   # test connectivity from dev namespace to default namespace, the expected result is \"command terminated with exit code 1\"\n   kubectl -n dev exec -t centos -- sh -c 'curl -m3 -sI http://frontend.default 2\u003e/dev/null | grep -i http'\n   ```\n\n   c. Test connectivity from each namespace dev and default to the Internet.\n   \n   ```bash   \n   # test connectivity from dev namespace to the Internet, the expected result is \"command terminated with exit code 1\"\n   kubectl -n dev exec -t centos -- sh -c 'curl -m3 -sI http://www.google.com 2\u003e/dev/null | grep -i http'\n   ```\n   \n   ```bash\n   # test connectivity from default namespace to the Internet, the expected result is \"HTTP/1.1 200 OK\"\n   kubectl exec -it $(kubectl get po -l app=loadgenerator -ojsonpath='{.items[0].metadata.name}') \\\n   -c main -- sh -c 'curl -m3 -sI http://www.google.com 2\u003e/dev/null | grep -i http'\n   ```\n\n4. Implement explicitic policy to allow egress access from a workload in one namespace/pod, e.g. dev/centos, to default/frontend.\n   \n   a. Deploy egress policy between two namespaces dev and default.\n\n   ```yaml\n   kubectl apply -f - \u003c\u003c-EOF\n   apiVersion: projectcalico.org/v3\n   kind: NetworkPolicy\n   metadata:\n     name: platform.centos-to-frontend\n     namespace: dev\n   spec:\n     tier: platform\n     order: 100\n     selector: app == \"centos\"\n     egress:\n       - action: Allow\n         protocol: TCP\n         source: {}\n         destination:\n           selector: app == \"frontend\"\n           namespaceSelector: projectcalico.org/name == \"default\"\n       - action: Pass\n     types:\n       - Egress\n   EOF\n   ```\n\n   b. Test connectivity between dev/centos pod and default/frontend service again, should be allowed now.\n\n   ```bash   \n   kubectl -n dev exec -t centos -- sh -c 'curl -m3 -sI http://frontend.default 2\u003e/dev/null | grep -i http'\n   #output is HTTP/1.1 200 OK\n   ```\n\n5. Apply the policies to allow the microservices to communicate with each other.\n\n   ```bash\n   kubectl apply -f ./manifests/east-west-traffic.yaml\n   ```\n\n6. Deploy the following security policy for allowing DNS access to all endpoints in the security ties.\n\n  ```yaml\n  kubectl apply -f - \u003c\u003c-EOF\n  apiVersion: projectcalico.org/v3\n  kind: GlobalNetworkPolicy\n  metadata:\n    name: security.allow-kube-dns\n  spec:\n    tier: security\n    order: 200\n    selector: all()\n    types:\n    - Egress    \n    egress:\n      - action: Allow\n        protocol: UDP\n        source: {}\n        destination:\n          selector: k8s-app == \"kube-dns\"\n          ports:\n          - '53'\n      - action: Pass\n  EOF\n  ```\n\n7. Use the Calico Cloud GUI to enforce the default-deny staged policy. After enforcing a staged policy, it takes effect immediatelly. The default-deny policy will start to actually deny traffic. \n\n---\n## Security Policy Recommender\n\nNotice that the Online Botique web site stop responding. That is because we didnt deploy any policy for the `frontend` worload.\n\nLet's see how Calico can help us to build a security policy in order to allow the traffic to frontend service.\n\nClick in the Policy Recommendation button in the Policy Board:\n\n![recommend-a-policy](https://user-images.githubusercontent.com/104035488/206473864-f70ac0dd-d50d-46e1-b95b-d0153c154a79.png)\n\nNow select the time range you will look back in the flow logs to recommend a policy based on them. Select the namespace of the application we want the recommended policy for (default), and the right service (frontend-XXXXXX-*).\n\nWhen you click on the \"Recommend\" button in the top right corner, you will see that Calico recommends to open the traffic to port 8080 on Ingress, so we would be able to reach the frontend application again. There is also lots of other ingress and egress rules that will be created. Click on \"Enforce\", and then the \"Back\" button.\n  \nThe policy will be created at the end of your policy chain (at the bottom of the default Tier). You must move the policy to the right order, so it can have effect. In our case, as we would like to hit this policy before the pci isolation policy is done (so we are able to reach the customer service before it is isolated), drag and drop the policy in the board to the right place as indicated by the figure below:\n\n![move-policy](https://user-images.githubusercontent.com/104035488/206474337-cad7d5ef-da72-4845-97ee-8911e3249e62.png)\n\nNow you should be able to access the Online Boutique application in your browser.\n\n---\n\n## DNS Policies and NetworkSets\n\n1. Implement DNS policy to allow the external endpoint access from a specific workload, e.g. `dev/centos`.\n\n   a. Apply a policy to allow access to `api.twilio.com` endpoint using DNS rule.\n\n   ```yaml\n   kubectl apply -f - \u003c\u003c-EOF\n   apiVersion: projectcalico.org/v3\n   kind: GlobalNetworkPolicy\n   metadata:\n     name: security.external-domain-access\n   spec:\n     tier: security\n     selector: (app == \"centos\" \u0026\u0026 projectcalico.org/namespace == \"dev\")\n     order: 100\n     types:\n       - Egress\n     egress:\n     - action: Allow\n       source:\n         selector: app == 'centos'\n       destination:\n         domains:\n         - '*.twilio.com'\n   EOF\n   ```\n   \n   Test the access to the endpoints:\n\n   ```bash\n   # test egress access to api.twilio.com\n   kubectl -n dev exec -t centos -- sh -c 'curl -m3 -skI https://api.twilio.com 2\u003e/dev/null | grep -i http'\n   ```\n\n   ```bash\n   # test egress access to www.google.com\n   kubectl -n dev exec -t centos -- sh -c 'curl -m3 -skI https://www.google.com 2\u003e/dev/null | grep -i http'\n   ```\n\n   Access to the `api.twilio.com` endpoint should be allowed by the DNS policy and any other external endpoints like `www.google.com` should be denied.\n\n   b. Modify the policy to include `*.google.com` in dns policy and test egress access to www.google.com again.\n\n   ```bash\n   # test egress access to www.google.com again and it should be allowed.\n   kubectl -n dev exec -t centos -- sh -c 'curl -m3 -skI https://www.google.com 2\u003e/dev/null | grep -i http'\n   ```\n\n2. Edit the policy to use a `NetworkSet` with DNS domain instead of inline DNS rule.\n\n   a. Apply a policy to allow access to `api.twilio.com` endpoint using DNS policy.\n\n   Deploy the Network Set\n\n   ```yaml\n   kubectl apply -f - \u003c\u003c-EOF\n   kind: GlobalNetworkSet\n   apiVersion: projectcalico.org/v3\n   metadata:\n     name: allowed-dns\n     labels: \n       type: allowed-dns\n   spec:\n     allowedEgressDomains:\n     - '*.twilio.com'\n   EOF\n   ```\n\n   b. Deploy the DNS policy using the network set\n\n   ```yaml\n   kubectl apply -f - \u003c\u003c-EOF\n   apiVersion: projectcalico.org/v3\n   kind: GlobalNetworkPolicy\n   metadata:\n     name: security.external-domain-access\n   spec:\n     tier: security\n     selector: (app == \"centos\" \u0026\u0026 projectcalico.org/namespace == \"dev\")\n     order: 100\n     types:\n       - Egress\n     egress:\n     - action: Allow\n       destination:\n         selector: type == \"allowed-dns\"\n   EOF\n   ```\n\n   c. Test the access to the endpoints.\n\n   ```bash\n   # test egress access to api.twilio.com\n   kubectl -n dev exec -t centos -- sh -c 'curl -m3 -skI https://api.twilio.com 2\u003e/dev/null | grep -i http'\n   ```\n\n   ```bash\n   # test egress access to www.google.com\n   kubectl -n dev exec -t centos -- sh -c 'curl -m3 -skI https://www.google.com 2\u003e/dev/null | grep -i http'\n   ```\n\n   d. Modify the `NetworkSet` to include `*.google.com` in dns domain and test egress access to www.google.com again.\n\n   ```bash\n   # test egress access to www.google.com again and it should be allowed.\n   kubectl -n dev exec -t centos -- sh -c 'curl -m3 -skI https://www.google.com 2\u003e/dev/null | grep -i http'\n   ```\n\n## Ingress Policies using NetworkSets\n\nThe NetworkSet can also be used to block access from a specific ip address or cidr to an endpoint in your cluster. To demonstrate it, we are going to block the access from your workstation to the Online Boutique frontend-external service.\n\n   a. Test the access to the frontend-external service\n\n   ```bash\n   curl -sI -m3 $(kubectl get svc frontend-external -ojsonpath='{.status.loadBalancer.ingress[0].hostname}') | grep -i http\n   ```\n   \n   b. Identify your workstation ip address and store it in a environment variable\n\n   ```bash\n   export MY_IP=$(curl ifconfig.me)\n   ```\n\n   c. Create a NetworkSet with your ip address on it.\n\n   ```yaml\n   kubectl apply -f - \u003c\u003c-EOF\n   kind: GlobalNetworkSet\n   apiVersion: projectcalico.org/v3\n   metadata:\n     name: ip-address-list\n     labels: \n       type: blocked-ips\n   spec:\n     nets:\n     - $MY_IP/32\n   EOF\n   ```\n   \n   d. Create the policy to deny access to the frontend service.\n\n   ```yaml\n   kubectl apply -f - \u003c\u003c-EOF\n   apiVersion: projectcalico.org/v3\n   kind: GlobalNetworkPolicy\n   metadata:\n     name: security.blockep-ips\n   spec:\n     tier: security\n     selector: app == \"frontend\"\n     order: 300\n     types:\n       - Ingress\n     ingress:\n     - action: Deny\n       source:\n         selector: type == \"blocked-ips\"\n       destination: {}\n     - action: Pass\n       source: {}\n       destination: {}\n   EOF\n   ```\n\n   e. Create a global alert for the blocked attempt from the ip-address-list to the frontend.\n\n   ```yaml\n   kubectl apply -f - \u003c\u003c-EOF   \n   apiVersion: projectcalico.org/v3\n   kind: GlobalAlert\n   metadata:\n     name: blocked-ips\n   spec:\n     description: \"A connection attempt from a blocked ip address just happened.\"\n     summary: \"[blocked-ip] ${source_ip} from ${source_name_aggr} networkset attempted to access ${dest_namespace}/${dest_name_aggr}\"\n     severity: 100\n     dataSet: flows\n     period: 1m\n     lookback: 1m\n     query: '(source_name = \"ip-address-list\")'\n     aggregateBy: [dest_namespace, dest_name_aggr, source_name_aggr, source_ip]\n     field: num_flows\n     metric: sum\n     condition: gt\n     threshold: 0\n   EOF\n   ```\n\n   a. Test the access to the frontend-external service. It is blocked now. Wait a few minutes and check the `Activity \u003e Alerts`.\n\n   ```bash\n   curl -sI -m3 $(kubectl get svc frontend-external -ojsonpath='{.status.loadBalancer.ingress[0].hostname}') | grep -i http\n   ```\n\n## Microsegmentation Sample\n\nCalico eliminates the risks associated with lateral movement in the cluster to prevent access to sensitive data and other assets. Calico provides a unified, cloud-native segmentation model and single policy framework that works seamlessly across multiple application and workload environments. It enables faster response to security threats\nwith a cloud-native architecture that can dynamically enforce security policy changes across cloud environments in milliseconds in response to an attack.\n\n ### Microsegmentation using label PCI = true on a namespace\n\n1. For the microsegmentation deploy a new example application\n\n   ```bash\n   kubectl apply -f https://raw.githubusercontent.com/regismartins/cc-aks-security-compliance-workshop/main/manifests/storefront-pci.yaml\n   ```\n\n2. Verify that all the workloads has the label `PCI=true`.\n\n   ```bash\n   kubectl get pods -n storefront --show-labels\n   ```\n\n3. Create a policy that only allows endpoints with label PCI=true to communicate.\n\n   ```yaml\n   kubectl apply -f - \u003c\u003c-EOF\n   apiVersion: projectcalico.org/v3\n   kind: GlobalNetworkPolicy\n   metadata:\n     name: security.pci-whitelist\n   spec:\n     tier: security\n     order: 100\n     selector: projectcalico.org/namespace == \"storefront\"\n     ingress:\n     - action: Deny\n       source:\n         selector: PCI != \"true\"\n       destination:\n         selector: PCI == \"true\"\n     - action: Pass\n       source:\n       destination:\n     egress:\n     - action: Allow\n       protocol: UDP\n       source: {}\n       destination:\n         selector: k8s-app == \"kube-dns\"\n         ports:\n         - '53'\n     - action: Deny\n       source:\n         selector: PCI == \"true\"\n       destination:\n         selector: PCI != \"true\"\n     - action: Pass\n       source:\n       destination:\n     types:\n     - Ingress\n     - Egress\n   EOF\n   ```\n\nNow only the pods labeled with PCI=true will be able to exchange information. Note that you can use different labels to create any sort of restrictions for the workloads communications.\n\n---\n\n## Infrastructure as Code - Deploy Security Policies using Terraform\n\nSecurity policies are part of the Calico CRDs (projectcalico.org), so once you have Calico installed the network policies and all other resources can be refered in a yaml or in a terraform code using kubernetes provider.\n\nThere are many providers that allow you to use yaml files with terraform. For this demo we will look into one of them:\n\n[**kubectl - Terraform Provider**](https://registry.terraform.io/providers/gavinbunney/kubectl/1.14.0)\n\nThis provider is the best way of managing Kubernetes resources in Terraform, by allowing you to use the thing Kubernetes loves best - yaml!\n\nChange directory to the terraform folder, init and apply the terraform code.\n\nConfigure your cluster name in the `terraform.tf` file and run the commands below.\n\n```bash\nterraform init\nterraform apply -auto-approve\n```\n\nCheck the Policies Board in the Calico Cloud GUI.\n\nNow remove the security policy by destroying the terraform implemention.\n\n```bash\nterraform destroy -auto-approve\n```\n\n## Customizing deployed policies using the Calico Cloud UI.\n\nIn the Calico Cloud GUI, go to the Policies Board, and select the policy `\u003cpolicy-name\u003e`.\n\nChange the policy and save.\n\n---\n\n## Policy lifecycle management\n\nWith Calico, teams can create, preview, and deploy security policies based on the characteristics and metadata\nof a workload. These policies can provide an automated and scalable way to manage and isolate workloads for\nsecurity and compliance. You can automate a validation step that ensures your security policy works properly before being committed. Calico can deploy your policies in a “staged” mode that will display which traffic is being allowed or denied before the policy rule is enforced. The policy can then be committed if it is operating properly. This step avoids any potential problems caused by incorrect, incomplete, or\nconflicting security policy definitions.\n\n1. Open a policy and check the change log\n\n![change-log](https://user-images.githubusercontent.com/104035488/192361358-33ad8ab4-0c86-4892-a775-4d3bfc72ba38.gif)\n\n---\n\n# Thank you!\n\n--- \n\n**Useful links**\n\n- [Project Calico](https://www.tigera.io/project-calico/)\n- [Calico Academy - Get Calico Certified!](https://academy.tigera.io/)\n- [O’REILLY EBOOK: Kubernetes security and observability](https://www.tigera.io/lp/kubernetes-security-and-observability-ebook)\n- [Calico Users - Slack](https://slack.projectcalico.org/)\n\n**Follow us on social media**\n\n- [LinkedIn](https://www.linkedin.com/company/tigera/)\n- [Twitter](https://twitter.com/tigeraio)\n- [YouTube](https://www.youtube.com/channel/UC8uN3yhpeBeerGNwDiQbcgw/)\n- [Slack](https://calicousers.slack.com/)\n- [Github](https://github.com/tigera-solutions/)\n- [Discuss](https://discuss.projectcalico.tigera.io/)\n\n---\n\n[:arrow_up: Back to the top](/README.md#calico-cloud-demo-on-an-eks-cluster)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftigera-solutions%2Fcc-demo-workload-security","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftigera-solutions%2Fcc-demo-workload-security","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftigera-solutions%2Fcc-demo-workload-security/lists"}