A production-grade 9-service microservices platform combining Kubernetes, GitOps, DevSecOps, progressive delivery, software supply-chain security, runtime protection, and full-stack observability.
Microservices Β· Kubernetes Β· GitOps Β· Kargo Promotion Β· DevSecOps Β· Progressive Delivery Β· Supply-Chain Security Β· Runtime Security Β· Observability
This project is a production-grade DevOps & GitOps microservices platform built around a realistic 9-service digital banking architecture.
It demonstrates both sides of modern platform engineering:
- Microservices architecture β independently deployable services, service-owned databases, API gateway routing, asynchronous messaging, distributed transactions, fault isolation, and service-level resilience.
- Production delivery platform β Kubernetes, GitOps, CI security gates, signed artifacts, admission policies, progressive delivery, observability, runtime security, TLS, secrets management, and automated rollback.
The platform is not a single application wrapped in Kubernetes. It is a distributed system composed of multiple independently deployable workloads with different runtimes, data ownership boundaries, dependencies, and release strategies.
The core operating rule is:
Git is the source of truth. Production is changed through reconciliation, not by manually applying manifests.
The platform implements:
- 9 independently deployable microservices
- service-owned PostgreSQL databases
- YARP API gateway routing
- RabbitMQ-based asynchronous messaging
- Redis-backed distributed platform components
- cross-service transaction saga with compensation
- service-level fault isolation and resilience
- automated container build and promotion
- immutable commit-SHA releases
- declarative GitOps deployment
- Argo CD app-of-apps
- Kargo continuous-promotion control plane
- Warehouse β Freight β Stage promotion model
- ordered sync waves
- canary and blue-green delivery
- automated health and metrics gates
- container vulnerability scanning
- SPDX SBOM generation
- keyless image signing -Rekor transparency logging
- Kyverno admission enforcement
- Falco runtime threat detection
- Prometheus metrics and alerting
- Loki log aggregation with Grafana Alloy
- Grafana dashboards
- HashiCorp Vault secret management
- automated TLS with cert-manager and Let's Encrypt
- operational rollback and recovery runbooks
The application layer consists of 9 independently deployable services behind a gateway.
ββββββββββββββββββββββββββββ
β Frontend β
β Angular + nginx β
ββββββββββββββ¬ββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββ
β API Gateway β
β YARP β
ββββββββββββββ¬ββββββββββββββ
β
βββββββββββββββββ¬ββββββββββββΌββββββββββββ¬ββββββββββββββββ
β β β β β
βΌ βΌ βΌ βΌ βΌ
Identity Account Transaction Payment Lending
β β β β β
βββββββββββββββββ΄βββββββ¬βββββ΄ββββββββββββ΄ββββββββββββββββ
β
βββββββββ΄βββββββββ
βΌ βΌ
Platform Fraud
FastAPI
+ Gateway + Frontend
= 9 deployable services
| Service | Responsibility | Runtime |
|---|---|---|
| Identity | authentication, sessions, devices, recovery | ASP.NET Core 8 |
| Account | account state and balances | ASP.NET Core 8 |
| Transaction | ledger, transfers, reconciliation, distributed transaction workflow | ASP.NET Core 8 |
| Payment | payment workflows and merchant-facing operations | ASP.NET Core 8 |
| Lending | lending workflows and repayment schedules | ASP.NET Core 8 |
| Platform | shared operational capabilities, audit and platform state | ASP.NET Core 8 |
| Fraud | risk scoring and fraud analysis | Python Β· FastAPI |
| Gateway | API routing and edge service composition | YARP Β· ASP.NET Core |
| Frontend | browser application and /api proxy |
Angular Β· nginx |
Each backend service owns its own data boundary.
Identity βββΊ identitydb
Account βββΊ accountdb
Transaction βββΊ transactiondb
Payment βββΊ paymentdb
Lending βββΊ lendingdb
Platform βββΊ platformdb
The services do not read each other's tables directly. Cross-service interaction happens through APIs and messaging.
This matters operationally because each service can be:
- deployed independently
- rolled back independently
- monitored independently
- scaled independently
- isolated when unhealthy
- released with a strategy appropriate to its risk
Money movement crosses service boundaries, so transfers use a saga with compensation rather than pretending a single database transaction can cover the whole system.
Debit Account
β
βββ FAIL βββΊ transaction fails, nothing moved
β
βΌ
Credit Account
β
βββ FAIL βββΊ compensate by refunding debit
β
βΌ
Complete Transaction
A background reconciler handles operations left mid-flight and helps detect stranded transaction state.
Critical operations use idempotency protection at the database level so duplicate requests cannot race and both succeed.
The platform also includes:
- RabbitMQ for asynchronous service communication
- Redis for distributed platform state and supporting workloads
- HashiCorp Vault for sensitive key material and application secrets
- Azure Database for PostgreSQL as the external database layer
The architecture deliberately accepts the operational complexity of microservices because the platform is designed around fault isolation and independent recovery.
A failure in one service should not require redeploying the whole banking platform.
That same separation carries into delivery:
One service changes
β
βΌ
Build only the required artifact
β
βΌ
Scan + sign
β
βΌ
Update GitOps state
β
βΌ
Argo CD detects change
β
βΌ
Only that workload rolls out
This is where the microservices architecture and the GitOps platform reinforce each other: small deployment units, isolated blast radius, independent rollback, and service-level observability.
Developer Push
β
βΌ
GitHub Actions
β
βββ Test / validate
βββ Build container images
βββ Trivy vulnerability gate
βββ Syft SPDX SBOM
βββ Push immutable SHA-tagged images
βββ Cosign keyless signing + Rekor
β
βΌ
Kargo Promotion Layer
β
βββ Warehouse discovers deployable artifacts
βββ Freight represents an immutable release candidate
βββ Production Stage records promotion state/history
βββ Promotion updates desired image tag in Git
β
βΌ
Argo CD
β
βββ Detect desired-state change
βββ Reconcile cluster
βββ Restore drift automatically
β
βΌ
Kyverno Admission
β
βββ Verify image identity + signature + digest
β
βΌ
Argo Rollouts
β
βββ Canary or Blue-Green
βββ Health analysis
βββ Prometheus metric analysis
βββ Promote / Abort / Rollback
β
βΌ
Production Workloads
β
βββ Prometheus / Alertmanager
βββ Loki / Grafana Alloy
βββ Grafana
βββ Falco / Falcosidekick
flowchart TB
DEV["Developer<br/>git push"]
subgraph CI["CI / Software Supply Chain"]
TEST["Tests & validation"]
BUILD["Build images<br/>commit-SHA tags"]
TRIVY["Trivy<br/>HIGH / CRITICAL gate"]
SBOM["Syft<br/>SPDX SBOM"]
REG["Docker Hub"]
SIGN["Cosign keyless signing<br/>GitHub OIDC + Rekor"]
TEST --> BUILD --> TRIVY --> SBOM --> REG --> SIGN
end
subgraph GITOPS["GitOps & Promotion"]
WAREHOUSE["Kargo Warehouse<br/>artifact discovery"]
FREIGHT["Kargo Freight<br/>immutable release candidate"]
STAGE["Kargo Stage<br/>production promotion"]
VALUES["Production image tags"]
ROOT["Root Application"]
APPS["Argo CD Applications"]
WAREHOUSE --> FREIGHT --> STAGE --> VALUES
ROOT --> APPS
end
subgraph CLOUD["Microsoft Azure"]
subgraph K3S["k3s Cluster"]
ARGO["Argo CD"]
KYVERNO["Kyverno"]
ROLLOUTS["Argo Rollouts"]
subgraph SERVICES["AEGIS Workloads"]
APPSVC["9 application services"]
VAULT["Vault"]
RMQ["RabbitMQ"]
REDIS["Redis"]
end
subgraph OBS["Observability"]
PROM["Prometheus"]
ALERT["Alertmanager"]
GRAF["Grafana"]
LOKI["Loki"]
ALLOY["Grafana Alloy"]
end
subgraph RUNTIME["Runtime Security"]
FALCO["Falco<br/>modern eBPF"]
SIDEKICK["Falcosidekick + UI"]
end
TRAEFIK["Traefik"]
CERT["cert-manager<br/>Let's Encrypt"]
end
PG["Azure Database<br/>for PostgreSQL"]
end
DEV --> TEST
SIGN --> WAREHOUSE
STAGE --> VALUES
VALUES --> ARGO
ROOT --> ARGO
ARGO --> KYVERNO
ARGO --> ROLLOUTS
ROLLOUTS --> APPSVC
KYVERNO --> APPSVC
APPSVC --> PG
APPSVC --> VAULT
APPSVC --> RMQ
APPSVC --> REDIS
PROM --> GRAF
LOKI --> GRAF
ALLOY --> LOKI
PROM --> ALERT
FALCO --> SIDEKICK
TRAEFIK --> APPSVC
CERT --> TRAEFIK
| Layer | Technology |
|---|---|
| Application Architecture | 9-service microservices platform |
| Backend Runtime | ASP.NET Core 8 |
| Fraud Runtime | Python 3.11 Β· FastAPI |
| Frontend | Angular Β· nginx |
| API Gateway | YARP |
| Messaging | RabbitMQ Β· MassTransit |
| Caching / Distributed State | Redis |
| Cloud | Microsoft Azure |
| Kubernetes | k3s |
| GitOps | Argo CD |
| Continuous Promotion | Kargo 1.11 β Project Β· Warehouse Β· Freight Β· Stage |
| Progressive Delivery | Argo Rollouts |
| CI | GitHub Actions |
| Container Registry | Docker Hub |
| Image Scanning | Trivy |
| SBOM | Syft β SPDX JSON |
| Image Signing | Sigstore Cosign β keyless OIDC |
| Transparency Log | Rekor |
| Admission Policy | Kyverno |
| Runtime Security | Falco β modern eBPF |
| Security Events | Falcosidekick + UI |
| Metrics | Prometheus |
| Alerting | Alertmanager |
| Cluster Metrics | kube-state-metrics Β· node-exporter |
| Logs | Loki |
| Log Collection | Grafana Alloy |
| Dashboards | Grafana |
| Secrets | HashiCorp Vault |
| Ingress | Traefik |
| TLS | cert-manager + Let's Encrypt |
| Packaging | Helm |
| Database | Azure Database for PostgreSQL |
The delivery design separates application source and CI from cluster desired state.
Application / CI Repository
β
β successful build only
βΌ
GitOps Repository
β
β read-only reconciliation
βΌ
Argo CD
β
βΌ
Kubernetes
This separation is deliberate.
CI is allowed to update only the deployment state required for promotion. The cluster only needs read access to the repository that describes it.
Two narrowly scoped deploy keys are used:
| Key | Held by | Access |
|---|---|---|
argocd-cluster-readonly |
Argo CD / cluster | Read-only |
aegis-ci-promote |
CI | Read/write for promotion |
A broad personal access token is intentionally avoided. The principle is:
One identity, one direction, one purpose.
.
βββ bootstrap/
β βββ root-app.yaml
β
βββ apps/
β βββ cert-manager.yaml
β βββ admission.yaml
β βββ base.yaml
β βββ infrastructure.yaml
β βββ runtime-security.yaml
β βββ observability.yaml
β βββ logs.yaml
β βββ promotion.yaml
β βββ identity.yaml
β βββ account.yaml
β βββ transaction.yaml
β βββ payment.yaml
β βββ lending.yaml
β βββ platform.yaml
β βββ fraud.yaml
β βββ gateway.yaml
β βββ frontend.yaml
β
βββ manifests/
β βββ namespace.yaml
β βββ ingress.yaml
β βββ redirect-middleware.yaml
β βββ analysis-template.yaml
β βββ promotion/
β β βββ project.yaml
β β βββ warehouse.yaml
β β βββ stage-production.yaml
β βββ admission/
β βββ certs/
β βββ infrastructure/
β βββ observability/
β βββ falco/
β βββ argocd/
β βββ services/
β
βββ charts/
β βββ aegis-service/
β
βββ environments/
β βββ base/
β βββ production/
β βββ values.yaml
β
βββ scripts/
The service chart replaces repeated deployment manifests with a reusable deployment pattern, while environment-specific values keep image tags and configuration declarative.
AEGIS deploys images using commit-derived SHA tags.
Example:
aegis-identity:sha-<commit>
aegis-account:sha-<commit>
aegis-transaction:sha-<commit>
aegis-payment:sha-<commit>
aegis-lending:sha-<commit>
aegis-platform:sha-<commit>
aegis-fraud:sha-<commit>
aegis-gateway:sha-<commit>
aegis-frontend:sha-<commit>
latest is not used as a production deployment reference.
Why:
- a SHA tag identifies exactly which source revision produced the image
- Git detects an actual desired-state change
- rollbacks target a known artifact
- a running Pod can be traced back to a commit
- mutable tags cannot silently change the software behind an unchanged manifest
Before promotion, CI verifies that all expected service images actually exist. This prevents a GitOps update from referencing a commit for which no deployable container image was produced.
The supply chain follows a fail-fast model: artifacts must pass required checks before becoming deployable.
Trivy scans built images for:
HIGHCRITICAL
The pipeline uses a blocking exit code so failed security gates stop the release.
Syft generates an SPDX JSON Software Bill of Materials for container images.
The SBOM is associated with the image so software-component evidence is not limited to temporary CI logs.
Images are signed using Sigstore Cosign keyless signing.
GitHub Actions
β
βββ GitHub OIDC identity
βΌ
Sigstore Fulcio
β
βββ short-lived certificate
βΌ
Cosign signature
β
βββ stored with the image
βΌ
Rekor transparency log
There is no long-lived private signing key stored in CI.
This reduces:
- signing-key theft risk
- manual signing-key rotation
- hidden signing events
- CI secret sprawl
The security question is not simply:
βIs this image signed?β
It is:
βWas this image signed by the expected CI identity for the expected repository and workflow?β
Argo CD answers:
Does the cluster match Git?
Kyverno adds another question:
Can the artifact named by Git be trusted?
The verify-aegis-images policy runs in Enforce mode for AEGIS application images.
It verifies that:
- the image has a valid Cosign signature
- the signature comes from the expected OIDC identity
- the image belongs to the expected workload scope
- the image digest is verified
- the artifact that was verified is the artifact that actually runs
Digest verification and mutation protect the deployment from a tag being repointed after verification.
A separate policy audits moving latest tags on workloads outside the enforced AEGIS image rule.
Argo CD deploys desired state. Kargo models how a release becomes the desired state.
That distinction is important:
Container Registry
β
βΌ
Kargo Warehouse
β
βΌ
Freight
β
βΌ
Stage
β
βΌ
Git commit
β
βΌ
Argo CD
β
βΌ
Kubernetes
Kargo is installed and managed by Argo CD as part of the platform rather than being configured manually outside GitOps.
A shell command or CI job can change an image tag, but after the job ends it has very little durable understanding of:
- which release candidates are available
- which candidate is deployed
- which candidate is waiting
- what artifact set belongs together
- what was promoted previously
- what should move from one environment to another later
Kargo turns promotion itself into Kubernetes-native state with history, health and explicit release objects.
The promotion model is scoped under a dedicated Kargo project:
aegis-delivery
Its configuration defines how Freight is allowed to move through Stages.
The Warehouse watches the AEGIS container stream and discovers release candidates.
kind: Warehouse
metadata:
name: aegis-images
namespace: aegis-deliveryA key design decision is to treat the banking platform as a coherent release unit.
All nine application images are produced from the same source commit and share the same sha-* version. The release model therefore represents βAEGIS at commit Xβ rather than allowing arbitrary combinations of unrelated service revisions to be promoted accidentally.
When Kargo discovers a valid artifact version, it represents that candidate as Freight.
Conceptually:
Freight
βββ AEGIS release @ sha-<commit>
The important property is that a release candidate becomes a named, traceable object instead of only a tag observed inside a transient CI log.
The current promotion pipeline contains a production Stage.
kind: Stage
metadata:
name: production
namespace: aegis-deliveryPromotion follows the GitOps rule:
Kargo does not deploy directly to the cluster.
Instead, Kargo:
- clones the GitOps repository,
- updates the production image version,
- commits the desired-state change,
- pushes that commit,
- lets Argo CD detect and reconcile it.
This keeps Argo CD as the only deployment controller and prevents a second system from bypassing Git.
flowchart LR
REG["Docker Hub<br/>signed SHA images"]
WH["Warehouse<br/>aegis-images"]
FR["Freight<br/>release candidate"]
ST["Stage<br/>production"]
GIT["GitOps repo<br/>production values"]
ARGO["Argo CD"]
ROLLOUT["Argo Rollouts"]
K8S["AEGIS workloads"]
REG --> WH --> FR --> ST --> GIT --> ARGO --> ROLLOUT --> K8S
Kargo uses distinct credentials rather than reusing the CI or Argo CD identity:
| Credential | Purpose |
|---|---|
kargo-api |
Kargo API signing key + admin authentication |
docker-hub |
read-only registry discovery |
gitops-repo |
write access for promotion commits |
The Kargo Git writer has its own deploy key. Sharing the CI deploy key would make the two writers indistinguishable in an audit and would couple their revocation.
The platform uses two Argo CD Applications:
promotion
βββ installs Kargo
promotion-config
βββ manages Project / Warehouse / Stage
The engine and promotion model are separated so Kargo can be upgraded without treating its controller-generated promotion history as ordinary Git drift.
Argo CD ignores Kargo-owned status fields for resources such as:
WarehouseStageProject
Otherwise Argo CD would continually attempt to revert state that Kargo legitimately owns.
The current production policy is deliberately configured with:
autoPromotionEnabled: falseThis is intentional while the existing CI promotion writer and Kargo coexist. Allowing two systems to automatically update the same production version would create a race between writers.
The migration path is:
Current
CI promotion ββββββββββββββββΊ Git ββΊ Argo CD
Kargo ββ observes / models
Target
Kargo Warehouse ββΊ Freight ββΊ Stage ββΊ Git ββΊ Argo CD
The Kargo Warehouse is also configured around a real operational constraint: Docker Hub registry discovery can consume significant request quota when NewestBuild must inspect many historical tags.
The repository documents the mitigation explicitly instead of hiding it:
- narrow candidate discovery
- reduced polling frequency
- promotion-time verification of all expected service images
- a parked Warehouse state when quota recovery is required
A future production evolution would use a registry/tagging strategy that supports efficient sortable release discovery without per-tag metadata scans.
Each tool owns a different concern:
| Tool | Responsibility |
|---|---|
| Kargo | Which release candidate should move forward? |
| Argo CD | Does the cluster match the approved Git state? |
| Argo Rollouts | Is the new revision healthy enough to receive traffic? |
Together:
Kargo
β chooses/promotes release
βΌ
Git
β desired state
βΌ
Argo CD
β reconciles
βΌ
Argo Rollouts
β validates rollout
βΌ
Production
This separation keeps artifact promotion, desired-state reconciliation, and traffic rollout independently auditable.
A single root Application bootstraps the platform.
root-app
β
βββ apps/
βββ cert-manager
βββ admission
βββ admission-policies
βββ base
βββ infrastructure
βββ runtime-security
βββ observability
βββ logs
βββ routes
βββ identity
βββ account
βββ transaction
βββ payment
βββ lending
βββ platform
βββ fraud
βββ gateway
βββ frontend
The complete platform is managed through 23 Argo CD Applications, including the root Application and supporting platform components.
- automated synchronization
- pruning of removed resources
- self-healing drift correction
- declarative Helm values
- ordered dependency deployment
- no routine manual
kubectl apply
Infrastructure dependencies are ordered declaratively so application services do not race components that are not ready yet.
Example:
Wave -1
βββ cert-manager
βββ Kyverno engine
Wave 0
βββ admission policies
βββ namespace
βββ ingress
βββ analysis templates
Wave 1
βββ Vault
βββ RabbitMQ
βββ Redis
βββ observability
βββ runtime security
Later
βββ AEGIS application services
The startup sequence is part of desired state rather than tribal knowledge or timing assumptions.
Not every difference from Git is accidental drift.
Some fields are legitimately changed by Kubernetes controllers. Argo CD is configured to ignore selected controller-owned fields where reconciliation would otherwise create a controller conflict.
Argo Rollouts updates Service selectors with ReplicaSet hashes while steering traffic.
If Argo CD continuously reverted those selectors, GitOps reconciliation and rollout reconciliation would fight each other and could direct traffic to the wrong revision.
Kyverno may mutate or expand policy state after admission. Selected controller-managed fields are excluded from drift enforcement.
Where charts generate internal values during render or installation, selected generated fields can be ignored to avoid meaningless perpetual drift.
GitOps should correct unwanted drift, not fight legitimate controller ownership.
AEGIS uses two release strategies based on the failure mode of each component.
Backend services use canary delivery.
A new revision receives only part of traffic while the stable revision remains available.
Stable revision
β
βΌ
Create canary revision
β
βΌ
Partial live traffic
β
βββ health analysis
βββ error-rate analysis
βββ latency analysis
β
βββ PASS βββΊ continue / promote
β
βββ FAIL βββΊ abort / remain stable
In this k3s implementation, traffic weighting is approximated through replica count because no service mesh is installed. With two replicas, the meaningful stages are approximately half traffic and full traffic.
Customer entry points use blue-green delivery.
Current version (Blue)
β
β continues serving production
βΌ
New version (Green)
β
βΌ
Pre-promotion analysis
β
βββ FAIL βββΊ reject Green
β
βββ PASS
β
βΌ
traffic cutover
β
βΌ
Green becomes active
The new version is validated beside the active version before production traffic is switched.
Two analysis patterns protect releases.
Asks:
Is the new revision actually responding?
Configuration:
- 5 checks
- 10 seconds apart
- zero tolerated failures
- expected HTTP response:
200 - parameterized service port
This catches workloads that start successfully but immediately become unhealthy.
Asks:
Is the canary hurting customers?
Key signals:
- error rate
< 5% - p95 latency
< 2s - measured against the canary revision
A health endpoint alone is not enough. A service can return 200 on /health while real requests fail.
# Follow a rollout
kubectl argo rollouts get rollout identity -n aegis --watch
# Promote
kubectl argo rollouts promote identity -n aegis
# Abort and hold stable
kubectl argo rollouts abort identity -n aegis
# Roll back
kubectl argo rollouts undo identity -n aegisThe observability stack combines metrics, logs, alerts, release visibility, and cluster telemetry.
kube-prometheus-stack provides:
- Prometheus
- Alertmanager
- Grafana
- kube-state-metrics
- node-exporter
ServiceMonitors scrape the AEGIS workloads.
Grafana Alloy collects workload logs and sends them to Loki.
Grafana provides one interface for:
- service health
- Kubernetes health
- request rates
- error rates
- latency
- rollout behaviour
- application logs
- alerts
Three purpose-built Grafana dashboards provide 34 panels:
| Dashboard | Panels | Focus |
|---|---|---|
| Platform Health | 11 | service health, request rates, error rates, latency, resources |
| Banking Operations | 15 | operational workload and transaction-platform signals |
| Releases | 8 | rollout revisions, analysis state, release progress |
The release dashboard is observational. Argo Rollouts remains responsible for promotion decisions.
Prometheus alert rules cover platform availability and workload health.
Alertmanager receives and groups firing alerts.
Useful diagnostic:
kubectl exec -n observability \
prometheus-observability-kube-prometh-prometheus-0 \
-c prometheus -- \
promtool query instant http://localhost:9090 \
'ALERTS{alertstate="firing"}'Watchdog intentionally remains firing as a dead-man's-switch signal proving the alerting pipeline itself is alive.
CI, scanning, signing, and admission policies judge software before or during deployment.
Falco observes actual workload behaviour after deployment.
The platform uses:
- Falco
- modern eBPF driver
- JSON output
- syscall-drop monitoring
- Falcosidekick
- Falcosidekick UI
- Prometheus ServiceMonitor
| Detection | Severity | Purpose |
|---|---|---|
| Shell opened in a banking container | WARNING | Interactive shells are not expected in application containers |
| Reconnaissance tooling | WARNING | Detect unexpected use of tools such as nc, nmap, curl, wget, or ssh |
| Credential material read | CRITICAL | Detect suspicious access to service-account or credential material |
| Vault data touched by non-Vault process | CRITICAL | Protect sensitive Vault storage paths |
The goal is to detect suspicious behaviour, not only known malicious files.
No application secret is committed to the GitOps repository.
Sensitive material is created or injected separately from Git.
HashiCorp Vault provides the application secret-management layer.
| Control | Implementation |
|---|---|
| Seal mechanism | Shamir secret sharing |
| Threshold | 3-of-5 shares |
| Service authentication | AppRole |
| Field encryption | AES-256-GCM keys supplied through Vault |
| Bootstrap | Scripted initialization / secret creation outside Git |
The design avoids embedding database credentials, Vault credentials, or cryptographic keys in deployment manifests.
All externally exposed platform interfaces are routed through Traefik.
TLS is managed by:
- cert-manager
- Let's Encrypt
- Kubernetes Certificate resources
- HTTP β HTTPS redirection
Internet
β
βΌ
Traefik
β
βββ Application
βββ Argo CD
βββ Grafana
βββ Prometheus
βββ Alertmanager
βββ Falcosidekick UI
Certificates are automatically issued and renewed through cert-manager.
The aegis namespace is configured around a restricted workload posture.
Controls include:
- non-root workloads
- dropped Linux capabilities
- seccomp
RuntimeDefault - restricted Pod Security posture
- signed-image admission for application workloads
- no
latestdeployment strategy - secrets excluded from Git
- HTTPS ingress
- runtime detection with Falco
Security is implemented in layers:
Source
β
βΌ
CI validation
β
βΌ
Container scanning
β
βΌ
SBOM
β
βΌ
Image signing
β
βΌ
GitOps desired state
β
βΌ
Kyverno admission
β
βΌ
Kubernetes hardening
β
βΌ
Falco runtime detection
The platform follows an app-of-apps bootstrap model.
# Apply the single root Application
kubectl apply -f bootstrap/root-app.yamlAfter that, Argo CD discovers and reconciles the child Applications.
Secrets and Vault initialization are intentionally separate from Git:
# Example secret bootstrap
./scripts/create-secrets.sh /path/to/application/.env
# Initialize / configure Vault after it is running
./scripts/bootstrap-vault.shThe exact secret material is never committed.
kubectl get applications -n argocd
kubectl get rollouts -n aegis
kubectl get pods -Akubectl get app <name> -n argocd \
-o jsonpath='{.status.operationState.phase} {.status.operationState.message}'kubectl exec -n aegis deploy/vault -c vault -- \
sh -c 'VAULT_ADDR=http://127.0.0.1:8200 vault status'kubectl argo rollouts get rollout identity -n aegis --watch- 9-service microservices architecture
- independently deployable services
- service-owned databases
- API gateway routing with YARP
- distributed transaction saga with compensation
- RabbitMQ asynchronous messaging
- Redis platform integration
- heterogeneous runtimes β ASP.NET Core + FastAPI + Angular
- Kubernetes deployment on Azure with k3s
- GitOps-based cluster management
- Argo CD app-of-apps
- Kargo continuous promotion control plane
- Kargo Project / Warehouse / Freight / Stage model
- Git-based Kargo promotion workflow
- dedicated Kargo registry and Git credentials
- sync-wave dependency ordering
- automated drift correction
- immutable SHA-tag releases
- cross-repository promotion
- canary delivery
- blue-green delivery
- automated release analysis
- Prometheus-based rollout metrics
- Trivy image vulnerability scanning
- Syft SPDX SBOM generation
- Cosign keyless image signing
- Rekor transparency logging
- Kyverno signature verification
- digest verification at admission
- Pod Security hardening
- HashiCorp Vault integration
- Prometheus metrics
- Alertmanager alerting
- Loki log aggregation
- Grafana Alloy collection
- Grafana dashboards
- Falco runtime detection
- Falcosidekick security event UI
- Traefik ingress
- cert-manager
- Let's Encrypt TLS
- operational runbooks and rollback procedures