diff --git a/stacks/k8s-portal/modules/k8s-portal/files/src/routes/+page.svelte b/stacks/k8s-portal/modules/k8s-portal/files/src/routes/+page.svelte index 2d13fa39..7b617fd0 100644 --- a/stacks/k8s-portal/modules/k8s-portal/files/src/routes/+page.svelte +++ b/stacks/k8s-portal/modules/k8s-portal/files/src/routes/+page.svelte @@ -5,9 +5,11 @@

Kubernetes Access Portal

-
- VPN Required — The cluster is on a private network. You need Headscale VPN access before kubectl will work. - See the Getting Started guide for VPN setup instructions. +
+ Fastest way in: open the web terminal or the + dashboard and sign in — no install, no VPN needed. Prefer your + own machine? The local-setup guide covers VPN + kubectl, and the + Getting Started page compares all three access paths.
@@ -26,6 +28,7 @@

Assigned namespaces: {data.namespaces.join(', ')}

Quick Commands

+

Run these as-is in the web terminal — it's already signed in as you.

 # Check your pods
 kubectl get pods -n {data.namespaces[0]}
@@ -47,16 +50,23 @@ vault write kubernetes/creds/{data.namespaces[0]}-deployer \
 
 	

Get Started

+

No setup — start now

+
    +
  1. Open the web terminal — a ready shell with kubectl, Vault and your repos already set up
  2. +
  3. Open the dashboard — point-and-click view of your workloads
  4. +
+

On your own machine

    {#if data.role === 'namespace-owner'} -
  1. Complete the namespace-owner onboarding guide
  2. +
  3. Follow the namespace-owner setup (VPN, kubectl, Vault, encrypted state)
  4. {:else} -
  5. Complete the onboarding guide (VPN, kubectl, git)
  6. +
  7. Follow the local setup (VPN, kubectl, git)
  8. {/if}
  9. Install kubectl and kubelogin
  10. Download your kubeconfig
  11. Run kubectl get namespaces to verify access
+

Compare all three access paths →

@@ -91,12 +101,12 @@ vault write kubernetes/creds/{data.namespaces[0]}-deployer \ border-radius: 6px; margin: 1rem 0; } - .callout.warning { - background: #fff3cd; - border-left: 4px solid #ffc107; + .callout.info { + background: #e8f4fd; + border-left: 4px solid #2196f3; } .callout a { - color: #856404; + color: #0d47a1; font-weight: 600; } diff --git a/stacks/k8s-portal/modules/k8s-portal/files/src/routes/onboarding/+page.svelte b/stacks/k8s-portal/modules/k8s-portal/files/src/routes/onboarding/+page.svelte index d6ec35b9..6b2d73dd 100644 --- a/stacks/k8s-portal/modules/k8s-portal/files/src/routes/onboarding/+page.svelte +++ b/stacks/k8s-portal/modules/k8s-portal/files/src/routes/onboarding/+page.svelte @@ -5,87 +5,175 @@

Getting Started

-

Welcome! Follow these steps to get access to the home Kubernetes cluster.

- - +

+ Welcome! There are three ways to reach the home Kubernetes cluster. Pick the one that fits — + the first two need zero setup and open right in your browser. +

-

Step 0 — Join the VPN

-

The cluster is on a private network (10.0.20.0/24). You need VPN access first.

+

Three ways in

+ + + + + + + + + + + + + + + + + + + +
PathBest forSetup
A — Web terminalJust want to start working nowNone — opens in your browser
B — Web dashboardClick around, watch your app, read logsNone — opens in your browser
C — Your own machinekubectl / Terraform locally, full controlVPN + one-line installer
+
+ Not sure? Start with the web terminal (Path A). + Everything is already installed and your repos are already cloned — you can run your first + kubectl command within a minute, from any device. +
+
+ +
+

Path A — Web terminal Recommended No setup

+

+ A full terminal that runs in your browser — nothing to install, works from any device + (even a tablet). It drops you into your own account on the shared workstation, with every + tool already set up. +

    -
  1. Install Tailscale for your OS
  2. -
  3. Run this in your terminal: -
    tailscale login --login-server https://headscale.viktorbarzin.me
    +
  4. Open t3.viktorbarzin.me
  5. +
  6. Sign in with your Authentik account (the same SSO login as this portal)
  7. +
  8. You land in a ready-to-use shell. Try it: +
    kubectl get pods -n YOUR_NAMESPACE
  9. -
  10. A browser window will open with a registration URL
  11. -
  12. Send that URL to Viktor via email (vbarzin@gmail.com) or Slack
  13. -
  14. Wait for approval (usually within a few hours)
  15. -
  16. Once approved, test:
    ping 10.0.20.100
+
+ Already done for you on the workstation: +
    +
  • kubectl + your kubeconfig, scoped to your namespaces (no login dance)
  • +
  • vault, terragrunt, terraform, sops, kubeseal
  • +
  • Your repos cloned under ~/code — the infra repo plus your own project repos
  • +
  • Claude Code, ready to pair with you on changes
  • +
+
+
+ No access yet? The workstation is provisioned per person. If + t3.viktorbarzin.me says you're not authorized, ask Viktor to add you + (vbarzin@gmail.com or Slack). +
-
-

Step 1 — Log in to the portal

-

Visit k8s-portal.viktorbarzin.me and sign in with your Authentik account.

-

If you don't have an account yet, ask Viktor to create one.

+
+

Path B — Web dashboard No setup

+

+ A point-and-click view of the cluster — browse your pods, read logs, restart a deployment, + check events. Nothing to install. +

+
    +
  1. Open k8s.viktorbarzin.me
  2. +
  3. Sign in with your Authentik account
  4. +
  5. + You're dropped straight into the Kubernetes Dashboard, already authenticated as you — + no token to paste. The portal injects your personal access token for you. +
  6. +
+
+ Scoped to your namespace(s): you can see and manage your own workloads, but not other + tenants'. This path uses a per-user token that does not depend on CLI login, so it + keeps working even if kubectl OIDC login is having a bad day — making it the + reliable fallback for Path C. +
-
-

Step 2 — Set up kubectl

-

Run one of these commands in your terminal to install everything automatically:

-

macOS

-

Requires Homebrew. Install it first if you don't have it.

-
bash <(curl -fsSL https://k8s-portal.viktorbarzin.me/setup/script?os=mac)
-

Linux

-
bash <(curl -fsSL https://k8s-portal.viktorbarzin.me/setup/script?os=linux)
-

Windows

-

Use WSL2 and follow the Linux instructions.

-
+
+

Path C — From your own machine

+

+ For running kubectl, vault and Terraform locally. This is the most + powerful path and the one to use for infrastructure changes — it just needs a bit more setup + because the cluster API lives on a private network. +

+ + +

+ {#if showNamespaceOwner} + Namespace owner — you'll also set up Vault and encrypted Terraform state so you can deploy + your own app stacks. + {:else} + General user — VPN, kubectl and git access. (Managing your own app stack? Switch to the + Namespace Owner tab above.) + {/if} +

- {#if showNamespaceOwner}
-

Step 3 — Log into Vault

-

Vault manages your secrets and issues dynamic Kubernetes credentials.

-
vault login -method=oidc
-

This opens your browser for Authentik SSO. After login, your token is saved to ~/.vault-token.

+

Step 1 — Join the VPN

+

The cluster API is on a private network (10.0.20.0/24), so you need VPN access first.

+
    +
  1. Install Tailscale for your OS
  2. +
  3. Run this in your terminal: +
    tailscale login --login-server https://headscale.viktorbarzin.me
    +
  4. +
  5. A browser window opens with a registration URL
  6. +
  7. Send that URL to Viktor via email (vbarzin@gmail.com) or Slack
  8. +
  9. Wait for approval (usually within a few hours)
  10. +
  11. Once approved, test:
    ping 10.0.20.100
  12. +
-

Step 4 — Verify kubectl access

-

Run this command. It will open your browser for OIDC login the first time:

-
kubectl get pods -n YOUR_NAMESPACE
-

You should see an empty list (no resources) or your running pods.

+

Step 2 — Install the tools

+

Run one of these to install everything automatically (kubectl, kubelogin, vault, terragrunt, terraform, kubeseal) and write your kubeconfig to ~/.kube/config-home:

+

macOS

+

Requires Homebrew. Install it first if you don't have it.

+
bash <(curl -fsSL https://k8s-portal.viktorbarzin.me/setup/script?os=mac)
+

Linux

+
bash <(curl -fsSL https://k8s-portal.viktorbarzin.me/setup/script?os=linux)
+

Windows

+

Use WSL2 and follow the Linux instructions.

-

Step 5 — Clone the infra repo

-
git clone https://github.com/ViktorBarzin/infra.git
+			

Step 3 — Verify access

+

Run this. The first time, it opens your browser for SSO login:

+
kubectl get {showNamespaceOwner ? 'pods -n YOUR_NAMESPACE' : 'namespaces'}
+

You should see your resources (or an empty list if you haven't deployed anything yet).

+
+ Browser login loops, or kubectl says "Unauthorized"? Command-line SSO + (OIDC) can occasionally be unavailable. When that happens, use the + web dashboard (Path B) or the + web terminal (Path A) — both authenticate a different way and + keep working — and let Viktor know. +
+

Connection error instead? Make sure the VPN is up: tailscale status.

+
+ + {#if showNamespaceOwner} +
+

Step 4 — Log into Vault

+

Vault manages your secrets and issues dynamic Kubernetes credentials.

+
vault login -method=oidc
+

This opens your browser for Authentik SSO. After login, your token is saved to ~/.vault-token.

+
+ +
+

Step 5 — Clone the infra repo

+
git clone https://github.com/ViktorBarzin/infra.git
 cd infra
-

This is where all the infrastructure configuration lives. Terraform state is committed as encrypted files.

-
+

This is where all the infrastructure configuration lives. Terraform state is committed as encrypted files.

+
-
-

Step 6 — Install tools

-

You need sops and terragrunt to work with infrastructure state:

-

macOS

-
brew install sops terragrunt
-

Linux

-
# sops
-curl -LO https://github.com/getsops/sops/releases/latest/download/sops-v3.9.4.linux.amd64
-sudo mv sops-*.linux.amd64 /usr/local/bin/sops && sudo chmod +x /usr/local/bin/sops
-
-# terragrunt
-curl -LO https://github.com/gruntwork-io/terragrunt/releases/latest/download/terragrunt_linux_amd64
-sudo mv terragrunt_linux_amd64 /usr/local/bin/terragrunt && sudo chmod +x /usr/local/bin/terragrunt
-
- -
-

Step 7 — Decrypt your state

-

Terraform state is encrypted with SOPS. Your Vault login gives you access to only your stacks.

-
# Make sure you're logged into Vault
+			
+

Step 6 — Decrypt your state

+

Terraform state is encrypted with SOPS. Your Vault login gives you access to only your stacks.

+
# Make sure you're logged into Vault
 vault login -method=oidc
 
 # Decrypt your stack's state
@@ -95,160 +183,157 @@ scripts/state-sync decrypt YOUR_NAMESPACE
 cd stacks/YOUR_NAMESPACE
 ../../scripts/tg plan
-
-

How state encryption works

-
-
-
vault login -method=oidc
-
-
Authentik SSO
-
-
~/.vault-token
-
-
-
-
scripts/tg plan
-
-
state-sync decrypt
-
-
Vault Transit
sops-state-YOUR_NS
-
-
-
-
terragrunt plan/apply
-
-
state-sync encrypt
-
-
git commit + push
+
+

How state encryption works

+
+
+
vault login -method=oidc
+
+
Authentik SSO
+
+
~/.vault-token
+
+
+
+
scripts/tg plan
+
+
state-sync decrypt
+
+
Vault Transit
sops-state-YOUR_NS
+
+
+
+
terragrunt plan/apply
+
+
state-sync encrypt
+
+
git commit + push
+
-
-
- Access control: You can only decrypt state for your own namespaces. - Each namespace has its own Vault Transit encryption key. Your Vault policy - (sops-user-YOUR_USERNAME) only grants access to your keys. -
-
+
+ Access control: You can only decrypt state for your own namespaces. + Each namespace has its own Vault Transit encryption key. Your Vault policy + (sops-user-YOUR_USERNAME) only grants access to your keys. +
+
-
-

Step 8 — Create your first app stack

-
    -
  1. Copy the template:
    cp -r stacks/_template stacks/myapp
    +			
    +

    Step 7 — Create your first app stack

    +
      +
    1. Copy the template:
      cp -r stacks/_template stacks/myapp
       mv stacks/myapp/main.tf.example stacks/myapp/main.tf
    2. -
    3. Edit stacks/myapp/main.tf — replace all <placeholders>
    4. -
    5. Store secrets in Vault: -
      vault kv put secret/YOUR_USERNAME/myapp DB_PASSWORD=secret123
      -
    6. -
    7. Apply your stack: -
      cd stacks/myapp && ../../scripts/tg apply
      -
    8. -
    9. Commit encrypted state: -
      cd ../..
      +					
    10. Edit stacks/myapp/main.tf — replace all <placeholders>
    11. +
    12. Store secrets in Vault: +
      vault kv put secret/YOUR_USERNAME/myapp DB_PASSWORD=secret123
      +
    13. +
    14. Apply your stack: +
      cd stacks/myapp && ../../scripts/tg apply
      +
    15. +
    16. Commit encrypted state: +
      cd ../..
       git add stacks/myapp/ state/stacks/myapp/terraform.tfstate.enc
       git commit -m "add myapp stack"
       git push
      -
    17. -
    -
    +
  2. +
+
-
-

Architecture Overview

-

Here's how your changes flow through the system:

+
+

Architecture Overview

+

Here's how your changes flow through the system:

-
-

Apply workflow

-
-
-
Your Machine
-
git pull
-
-
scripts/tg plan
-
auto-decrypt
-
scripts/tg apply
-
auto-encrypt
-
git push
-
-
-
Vault
-
OIDC auth
Authentik SSO
-
-
Transit decrypt
sops-state-*
-
-
Transit encrypt
per-stack key
-
-
-
Cluster
-
K8s API
-
-
Your namespace
pods, services
-
-
Traefik ingress
*.viktorbarzin.me
+
+

Apply workflow

+
+
+
Your Machine
+
git pull
+
+
scripts/tg plan
+
auto-decrypt
+
scripts/tg apply
+
auto-encrypt
+
git push
+
+
+
Vault
+
OIDC auth
Authentik SSO
+
+
Transit decrypt
sops-state-*
+
+
Transit encrypt
per-stack key
+
+
+
Cluster
+
K8s API
+
+
Your namespace
pods, services
+
+
Traefik ingress
*.viktorbarzin.me
+
-
-
-

Security model

- - - - - - - - - -
LayerWhatHow
AuthenticationWho are you?Authentik SSO (OIDC) → Vault token
AuthorizationWhat can you access?Vault policy (sops-user-*) scoped to your namespaces
Encryption at restState in gitSOPS + Vault Transit (per-stack key)
Encryption fallbackBootstrap / DRage keys (admin only)
NetworkCluster accessHeadscale VPN (private 10.0.20.0/24)
-
-
- {:else} -
-

Step 3 — Verify access

-

Run this command. It will open your browser for login the first time:

-
kubectl get namespaces
-

You should see output like:

-
NAME              STATUS   AGE
-default           Active   200d
-kube-system       Active   200d
-monitoring        Active   200d
-...
-

If you get a connection error, make sure your VPN is connected (tailscale status).

-
- -
-

Step 4 — Clone the repo

-
git clone https://github.com/ViktorBarzin/infra.git
+				
+

Security model

+ + + + + + + + + +
LayerWhatHow
AuthenticationWho are you?Authentik SSO (OIDC) → Vault token
AuthorizationWhat can you access?Vault policy (sops-user-*) scoped to your namespaces
Encryption at restState in gitSOPS + Vault Transit (per-stack key)
Encryption fallbackBootstrap / DRage keys (admin only)
NetworkCluster accessHeadscale VPN (private 10.0.20.0/24)
+
+
+ {:else} +
+

Step 4 — Clone the repo

+
git clone https://github.com/ViktorBarzin/infra.git
 cd infra
-

This is where all the infrastructure configuration lives.

-
+

This is where all the infrastructure configuration lives.

+
-
-

Step 5 — Your first change

-
    -
  1. Create a branch:
    git checkout -b my-first-change
  2. -
  3. Edit a service file (e.g., change an image tag in stacks/echo/main.tf)
  4. -
  5. Commit and push:
    git add . && git commit -m "my first change" && git push -u origin my-first-change
  6. -
  7. Open a Pull Request on GitHub
  8. -
  9. Viktor reviews and merges
  10. -
  11. Woodpecker CI automatically applies the change to the cluster
  12. -
  13. Slack notification confirms it worked
  14. -
-
- {/if} +
+

Step 5 — Your first change

+
    +
  1. Create a branch:
    git checkout -b my-first-change
  2. +
  3. Edit a service file (e.g., change an image tag in stacks/echo/main.tf)
  4. +
  5. Commit and push:
    git add . && git commit -m "my first change" && git push -u origin my-first-change
  6. +
  7. Open a Pull Request on GitHub
  8. +
  9. Viktor reviews and merges
  10. +
  11. Woodpecker CI automatically applies the change to the cluster
  12. +
  13. Slack notification confirms it worked
  14. +
+
+ {/if} +