Skip to content

nikogura/kubectl-ssh-oidc

Repository files navigation

kubectl-ssh-oidc

Go Report Card License: MIT Release

A kubectl plugin that provides passwordless authentication to Kubernetes clusters using SSH keys and Dex Identity Provider with SSH connector support.

Note: This repository contains only the kubectl plugin. The server-side SSH connector for Dex is maintained in a separate fork at github.com/nikogura/dex and is intended for upstream contribution to Dex.

🚀 Overview

This plugin eliminates the need for passwords, browser-based OAuth flows, or manually managing tokens by leveraging your existing SSH infrastructure. It combines SSH key authentication with OIDC to provide seamless Kubernetes access.

Key Benefits

  • Passwordless: Uses SSH keys from ssh-agent or filesystem
  • No Browser Required: Direct CLI authentication
  • Flexible SSH Keys: Works with ssh-agent, filesystem keys, or encrypted keys
  • Standard SSH Behavior: Follows SSH client key discovery and iteration
  • Passphrase Support: Interactive prompts for encrypted private keys
  • Hardware Security: Supports hardware-backed SSH keys (PKCS#11, PIV cards)
  • Centralized Identity: Integrates with Dex for user/group management
  • Standard OIDC: Works with any Kubernetes cluster supporting OIDC

🏗️ Architecture

graph LR
    A[kubectl] --> B[kubectl-ssh-oidc plugin]
    B --> C[ssh-agent]
    B --> F[~/.ssh/id_*]
    B --> D[Dex IDP]
    D --> E[Kubernetes API Server]
    
    C -.->|SSH Key Signature| B
    F -.->|SSH Key Signature| B
    D -.->|OIDC Token| B
    B -.->|ExecCredential| A
Loading

Authentication Flow:

  1. User runs kubectl command
  2. kubectl calls kubectl-ssh-oidc plugin
  3. Plugin discovers SSH keys from ssh-agent and/or filesystem (standard SSH locations)
  4. Plugin creates JWT with dual audience model:
    • aud: Dex instance ID (ensures JWT is for correct Dex instance)
    • target_audience: Desired audience for final OIDC tokens (optional)
    • Standard claims: sub, iss, jti, exp, iat, nbf
  5. Plugin signs JWT directly using SSH private key (follows jwt-ssh-agent pattern)
  6. Plugin exchanges signed JWT with Dex using OAuth2 Token Exchange (RFC 8693)
  7. Dex validates JWT signature against administrator-configured SSH keys and returns OIDC token
  8. kubectl uses OIDC token to authenticate with Kubernetes API

Security Model: JWT contains no SSH keys or fingerprints - it's just a packaging format. All SSH keys and user mappings are configured by administrators in Dex, preventing key injection attacks.

📦 Installation

Quick Install

# Download latest release for your platform
# Linux AMD64
curl -L "https://github.com/nikogura/kubectl-ssh-oidc/releases/latest/download/kubectl-ssh_oidc-linux-amd64" -o kubectl-ssh-oidc

# Linux ARM64 (Raspberry Pi, AWS Graviton, etc.)
curl -L "https://github.com/nikogura/kubectl-ssh-oidc/releases/latest/download/kubectl-ssh_oidc-linux-arm64" -o kubectl-ssh-oidc

# macOS AMD64 (Intel)
curl -L "https://github.com/nikogura/kubectl-ssh-oidc/releases/latest/download/kubectl-ssh_oidc-darwin-amd64" -o kubectl-ssh-oidc

# macOS ARM64 (Apple Silicon)
curl -L "https://github.com/nikogura/kubectl-ssh-oidc/releases/latest/download/kubectl-ssh_oidc-darwin-arm64" -o kubectl-ssh-oidc

# Windows AMD64 (PowerShell)
# curl.exe -L "https://github.com/nikogura/kubectl-ssh-oidc/releases/latest/download/kubectl-ssh_oidc-windows-amd64.exe" -o kubectl-ssh-oidc.exe

# Make executable and install (Linux/macOS)
chmod +x kubectl-ssh-oidc
sudo mv kubectl-ssh-oidc /usr/local/bin/

Go Install (Recommended for Go users)

# Install directly from GitHub (requires Go 1.21+)
go install github.com/nikogura/kubectl-ssh-oidc@latest

Note: The binary will be installed to $GOPATH/bin/kubectl-ssh-oidc or $HOME/go/bin/kubectl-ssh-oidc. Ensure this directory is in your PATH.

Build from Source

git clone https://github.com/nikogura/kubectl-ssh-oidc
cd kubectl-ssh-oidc

# Build and install to user directory
make install

# Or install system-wide (requires sudo)
make install-system

⚙️ Configuration

1. SSH Key Setup (Flexible Options)

The plugin supports multiple SSH key sources and follows standard SSH client behavior:

Option A: SSH Agent (Recommended)

# Start ssh-agent (if not running)
eval $(ssh-agent -s)

# Add your SSH key
ssh-add ~/.ssh/id_ed25519

# Verify keys are loaded
ssh-add -l

Option B: Filesystem Keys (No Agent Required)

# Plugin automatically discovers keys from standard locations:
# ~/.ssh/id_ed25519, ~/.ssh/id_rsa, ~/.ssh/id_ecdsa, etc.

# For encrypted keys, you'll be prompted for passphrase:
# Enter passphrase for /home/user/.ssh/id_ed25519: [hidden]

# Custom key paths via environment variable:
export SSH_KEY_PATHS="/path/to/key1:/path/to/key2"
export SSH_USE_AGENT=false  # Disable agent, use only filesystem

Option C: Mixed (Agent + Filesystem)

# Plugin tries agent keys first, then filesystem keys
# This is the default behavior - no configuration needed
export SSH_USE_AGENT=true   # Default: true

2. Get SSH Key Information for Dex Configuration

The SSH connector requires users, and their public keys to be configured.

Alternatively, you can use the complete public key content from your .pub files:

# Copy the entire content of your public key file
cat ~/.ssh/id_ed25519.pub
cat ~/.ssh/id_rsa.pub

Example output:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKj8v5Z2b7N4T... user@hostname
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC9Uxzcz0x... user@hostname

Notes about SSH public key format:

  • ✅ Algorithm and key data are required: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5...
  • ✅ Comment/hostname is optional: ssh-ed25519 AAAAC3... user@hostname or just ssh-ed25519 AAAAC3...
  • ✅ Both formats can be mixed in the same user configuration
  • ✅ The connector ignores the 3rd comment field.

3. Generate Client Credentials

Generate secure client credentials for the Dex static client:

# Generate a secure client ID (32 character hex string)
openssl rand -hex 16

# Generate a secure client secret (base64 encoded)
openssl rand -base64 32

4. Configure Dex

Important: This kubectl plugin requires a Dex instance with SSH connector support. The SSH connector is not yet available in upstream Dex. You must use the Dex fork at github.com/nikogura/dex that includes the SSH connector implementation.

Create or update your Dex configuration (use the public keys from step 2 and credentials from step 3):

# dex-config.yaml
issuer: https://dex.example.com

staticClients:
- id: your-generated-client-id        # Generate secure random client ID
  name: 'kubectl SSH OIDC Plugin'
  secret: your-generated-client-secret # Generate secure random client secret

connectors:
- type: ssh
  id: ssh
  name: SSH Key Authentication
  config:
    # Multiple keys per user - SUPPORTS BOTH FORMATS
    users:
      "john.doe":
        keys:
        - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExample... user@hostname"
        - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC9Uxzcz0x... user@hostname"
        username: "john.doe"
        email: "john.doe@example.com"
        full_name: "John Doe"
        groups:
        - "developers"
        - "kubernetes-users"

      "jane.smith":
        keys:
        - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAnother... jane@hostname" 
        username: "jane.smith"
        email: "jane.smith@example.com"
        full_name: "Jane Smith"
        groups:
        - "developers"
        - "team-leads"
    
    allowed_issuers:
    - "kubectl-ssh-oidc"
    
    # NEW: Dual audience model for secure instance validation
    dex_instance_id: "https://dex.example.com"        # Ensures JWTs are for this Dex instance
    allowed_target_audiences:                          # Controls final token audiences
    - "your-generated-client-id"                       # Must match staticClients configuration
    - "kubectl"                                        # Standard kubectl client ID

    # DEPRECATED: Legacy single-audience support (for backward compatibility)
    allowed_clients:
    - "your-generated-client-id"                       # Still supported during migration
    
    default_groups:
    - "authenticated"
    
    token_ttl: 3600  # Optional: Token lifetime in seconds (defaults to 3600 if not specified)

5. Build and Deploy Dex with SSH Connector

Important: You must use the Dex fork at github.com/nikogura/dex which includes the SSH connector implementation.

Building from Source

# 1. Clone the Dex fork with SSH connector
git clone https://github.com/nikogura/dex
cd dex

# 2. Build the Dex binary
make build

# 3. The binary will be in bin/dex
./bin/dex version

Building Docker Image

# Build Docker image with SSH connector
docker build -t dex-ssh:latest .

# Tag for your registry (optional)
docker tag dex-ssh:latest your-registry.com/dex-ssh:v2.44.0

# Push to registry (optional)
docker push your-registry.com/dex-ssh:v2.44.0

Deployment Options

Option A: Docker

# Run with your config file
docker run -d \
  -p 5556:5556 \
  -v /path/to/your/dex-config.yaml:/etc/dex/config.yaml \
  dex-ssh:latest \
  serve /etc/dex/config.yaml

Option B: Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dex
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dex
  template:
    metadata:
      labels:
        app: dex
    spec:
      containers:
      - name: dex
        image: your-registry.com/dex-ssh:v2.44.0
        ports:
        - containerPort: 5556
        command: ["dex", "serve", "/etc/dex/cfg/config.yaml"]
        volumeMounts:
        - name: config
          mountPath: /etc/dex/cfg
      volumes:
      - name: config
        configMap:
          name: dex-config

Option C: systemd Service

# Copy binary to system location
sudo cp bin/dex /usr/local/bin/

# Create systemd service
sudo tee /etc/systemd/system/dex.service << EOF
[Unit]
Description=Dex OIDC Identity Provider
After=network.target

[Service]
Type=simple
User=dex
Group=dex
ExecStart=/usr/local/bin/dex serve /etc/dex/config.yaml
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

# Enable and start service
sudo systemctl enable dex
sudo systemctl start dex

The SSH connector supports both legacy direct token authentication and OAuth2 Token Exchange (RFC 8693).

6. Configure Kubernetes Cluster

Update your kube-apiserver to accept OIDC tokens:

# kube-apiserver configuration
apiServer:
  extraArgs:
    oidc-issuer-url: "https://dex.example.com"
    oidc-client-id: "kubernetes"
    oidc-username-claim: "email"
    oidc-groups-claim: "groups"

7. Configure kubectl

Update your kubeconfig with environment variables for secure credential management:

apiVersion: v1
kind: Config
users:
- name: ssh-oidc-user
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1
      command: kubectl-ssh-oidc
      env:
      - name: DEX_URL
        value: "https://dex.example.com"
      - name: CLIENT_ID
        value: "your-client-id"         # Generated client ID from Dex config
      - name: CLIENT_SECRET
        value: "your-client-secret"     # Generated client secret from Dex config
      - name: DEX_INSTANCE_ID
        value: "https://dex.example.com"  # NEW: Dex instance ID for security
      - name: TARGET_AUDIENCE
        value: "your-client-id"         # NEW: Target audience for tokens
      - name: KUBECTL_SSH_USER
        value: "your-username"

contexts:
- name: ssh-oidc-context
  context:
    cluster: your-cluster
    user: ssh-oidc-user

🎯 Usage

Username Configuration

The plugin requires a username for the JWT sub claim to identify which user to authenticate in Dex. You can specify this in three ways:

  1. Command line argument (3rd argument):

    kubectl-ssh-oidc https://dex.example.com kubectl-ssh-oidc your-username
  2. Environment variable:

    export KUBECTL_SSH_USER=your-username
    kubectl-ssh-oidc https://dex.example.com kubectl-ssh-oidc
  3. System username fallback: If neither is provided, uses your system username ($USER)

Important: The username must match a user configured in your Dex SSH connector configuration.

Basic Usage

# Use the SSH OIDC context
kubectl config use-context ssh-oidc-context

# Now all kubectl commands authenticate via SSH
kubectl get pods
kubectl get nodes
kubectl logs deployment/my-app

Environment Variables

# Authentication settings
export DEX_URL="https://dex.example.com"
export CLIENT_ID="your-generated-client-id"    # From Dex staticClients configuration
export CLIENT_SECRET="your-client-secret"      # From Dex staticClients configuration
export DEX_INSTANCE_ID="https://dex.example.com"  # NEW: Dex instance ID for security
export TARGET_AUDIENCE="your-generated-client-id" # NEW: Target audience for final tokens
export AUDIENCE="kubernetes"                   # DEPRECATED: Legacy audience support
export CACHE_TOKENS="true"
export KUBECTL_SSH_USER="your-username"        # Username for authentication

# SSH behavior control
export SSH_USE_AGENT="true"                    # Use SSH agent (default: true)
export SSH_IDENTITIES_ONLY="false"             # Only use specified keys (default: false)
export SSH_KEY_PATHS="/path/to/key1:/path/to/key2"  # Custom SSH key paths

Direct Plugin Usage

# Generate credentials manually (uses agent + filesystem keys)
kubectl-ssh-oidc https://dex.example.com kubectl-ssh-oidc your-username

# Use only filesystem keys (no agent)
SSH_USE_AGENT=false kubectl-ssh-oidc https://dex.example.com kubectl-ssh-oidc your-username

# Use specific key only
SSH_KEY_PATHS="/home/user/.ssh/id_ed25519" SSH_IDENTITIES_ONLY=true \
  kubectl-ssh-oidc https://dex.example.com kubectl-ssh-oidc your-username

# Using environment variable for username
export KUBECTL_SSH_USER=your-username
kubectl-ssh-oidc https://dex.example.com kubectl-ssh-oidc

🔐 RBAC Configuration

Create RBAC rules for your users and groups:

# Developer access
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: ssh-oidc-developers
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: edit
subjects:
- kind: Group
  name: "developers"
  apiGroup: rbac.authorization.k8s.io

---
# Admin access
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: ssh-oidc-admins
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: Group
  name: "kubernetes-admins"
  apiGroup: rbac.authorization.k8s.io

🛠️ Development

Prerequisites

  • Go 1.21+
  • SSH agent with loaded keys
  • Running Dex instance

Build

# Build for current platform
make build

# Cross-compile for all platforms
make build-all

# Run tests
make test

# Run integration tests (includes unit tests + lint as prerequisites)
make test-integration-local

# Run all tests (unit + lint + full integration with Docker)
make test-all

# Lint code
make lint

Project Structure

kubectl-ssh-oidc/
├── main.go                   # Main plugin executable
├── pkg/
│   ├── kubectl/              # kubectl plugin implementation
│   │   └── mocks/            # Mock objects for testing
├── test/                     # Test tools and example configuration
│   ├── dex-config.yaml       # Example Dex configuration with SSH connector
│   └── test.go               # Standalone test tool for OAuth2 Token Exchange
│   └── helpers.go            # Test helper functions and mock data
├── test_integration.go       # End-to-end integration tests
├── Makefile                  # Build automation
├── README.md                 # This file
├── Usage.md                  # Usage documentation
└── go.mod                    # Go module definition

Note: The Dex SSH connector implementation is maintained in the separate fork at github.com/nikogura/dex.

🔧 Troubleshooting

Check SSH Agent Status

make check-ssh

Common Issues

Issue Solution
No SSH keys found Ensure keys in ~/.ssh/ or add to agent: ssh-add ~/.ssh/id_ed25519
SSH agent not running eval $(ssh-agent -s) or use SSH_USE_AGENT=false
signature type ssh-ed25519 for key type ssh-rsa Fixed in v0.0.18+: SSH signature verification now correctly matches key types. Update to latest version.
JWT token validation failed / Unauthorized Fixed in latest: Implemented multiple token authentication system where Dex returns tokens signed with all available keys, allowing kubectl to select the correct token that matches Kubernetes API server expectations.
Key not authorized in Dex Check public key is configured in Dex
User not found in Dex Set username: kubectl-ssh-oidc https://dex.example.com kubectl-ssh-oidc your-username or export KUBECTL_SSH_USER=your-username
Passphrase prompt fails Ensure TTY available or use unencrypted keys
OIDC validation failed Verify kube-apiserver OIDC settings
Permission denied Check RBAC configuration
Multiple key errors Check detailed error output for each key attempt

Debug Mode

# Enable debug output
export DEBUG=true
kubectl-ssh-oidc https://dex.example.com kubectl-ssh-oidc your-username

# Check what username will be used
echo "Username: ${KUBECTL_SSH_USER:-$(whoami)}"

Test Client

A standalone test client is provided to demonstrate and test the OAuth2 Token Exchange flow:

# Build the test tool
cd test
go build -o test test.go

# Test authentication flow (requires SSH agent with loaded key)
./test https://dex.example.com username

# Example output:
# Testing kubectl-ssh-oidc authentication
# ===================================
# Dex URL: https://dex.example.com
# Username: username
# SSH Agent: $SSH_AUTH_SOCK = /tmp/ssh-agent.sock
#
# 1. Creating SSH-signed JWT...
#    ✅ SSH JWT created
#
# 2. Exchanging SSH JWT via OAuth2 Token Exchange...
#    ✅ Token exchange successful
#
# 3. Results:
#    Access Token: eyJhbGciOiJSUzI1NiIsImtpZCI6...
#    ID Token: eyJhbGciOiJSUzI1NiIsImtpZCI6...
#
# 4. Validating ID token structure:
#      - Algorithm: RS256 ✅
#      - Subject: username ✅
#      - Issuer: https://dex.example.com ✅
#      - Audience: kubernetes ✅
#      - Groups: [admin, developers] ✅
#      - Email: username@example.com ✅
#    ✅ ID token is valid for Kubernetes
#
# 🎉 kubectl-ssh-oidc authentication test successful!

Requirements:

  • SSH agent running with authorized key loaded
  • Dex instance running with SSH connector configured
  • User configured in Dex SSH connector configuration

🔄 Migration from Legacy Audience Model

The kubectl-ssh-oidc plugin now supports a new dual audience model for enhanced security while maintaining backward compatibility with existing deployments.

Migration Benefits

  • Enhanced Security: Prevents JWT replay attacks across different Dex instances
  • Flexible Token Audiences: Control what audiences can be requested in final OIDC tokens
  • Zero Downtime: Gradual migration path with full backward compatibility

Migration Steps

Phase 1: Update Dex Configuration

connectors:
- type: ssh
  config:
    # NEW: Add dual audience fields
    dex_instance_id: "https://dex.example.com"    # Your Dex issuer URL
    allowed_target_audiences:                      # Migrate from allowed_clients
      - "kubectl"
      - "your-client-id"

    # KEEP: Legacy field for backward compatibility during migration
    allowed_clients:
      - "your-client-id"  # Existing clients continue working

Phase 2: Update Client Configuration

# NEW dual-audience kubeconfig (recommended)
users:
- name: ssh-oidc-user
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1
      command: kubectl-ssh-oidc
      env:
      - name: DEX_INSTANCE_ID
        value: "https://dex.example.com"  # NEW: Ensures JWT is for this Dex instance
      - name: TARGET_AUDIENCE
        value: "kubectl"                  # NEW: Desired audience for final tokens
      - name: DEX_URL
        value: "https://dex.example.com"
      - name: CLIENT_ID
        value: "your-client-id"
      # ... other existing config

Phase 3: Verify Migration

Monitor your Dex logs to see migration progress:

SSH_AUDIT: type=token_type username=alice status=info details="processing new_dual_audience token"
SSH_AUDIT: type=token_type username=bob status=info details="processing legacy_single_audience token"

Phase 4: Clean Up (Optional)

Once all clients show "new_dual_audience" in logs:

# Remove legacy fields from Dex configuration
connectors:
- type: ssh
  config:
    dex_instance_id: "https://dex.example.com"
    allowed_target_audiences:
      - "kubectl"
      - "your-client-id"
    # allowed_clients can now be removed

Rollback Support

If issues occur during migration:

  1. Keep allowed_target_audiences configured
  2. Legacy clients continue working unchanged
  3. No service interruption during rollback

🔒 Security Model and Considerations

Security Architecture

This plugin implements a secure JWT-based authentication model designed to prevent common security vulnerabilities:

JWT is Just a Packaging Format: JWTs contain no trusted data until cryptographic verification succeeds against keys configured by Dex administrators.

Administrative Control Model: The Dex configuration provides complete access control:

  • WHO can connect: Only users explicitly configured in Dex can authenticate
  • HOW they prove identity: Each user's configured SSH keys define which private keys can cryptographically prove the user's identity
  • WHAT they can access: User configuration determines scopes (email, groups, permissions)

Identity Claim and Proof: Users prove their identity through a two-step process:

  1. Identity Claim: User sets the sub field in the JWT to claim their identity
  2. Cryptographic Proof: User signs the JWT with their SSH private key to prove they control that identity

Security Separation: Authentication (cryptographic proof via SSH key signature) is completely separated from authorization (administrative policy configured in Dex), preventing clients from influencing their own permissions.

No Key Injection: JWTs cannot contain verification keys that clients control - all trusted SSH keys and user mappings are configured by Dex administrators, preventing privilege escalation attacks.

Security Best Practices

  • SSH Key Security: Use strong key types (Ed25519, RSA 4096+, ECDSA P-384)
  • Key Rotation: Regularly rotate SSH keys and update Dex configuration
  • Hardware Keys: Consider using hardware-backed SSH keys (YubiKey, etc.)
  • Network Security: Always use TLS for Dex and Kubernetes API communications
  • Audit Logging:
    • Enable audit logging in Kubernetes for authentication events
    • SSH connector provides comprehensive audit logs with structured format:
      SSH_AUDIT: type=auth_success username=john.doe key=ssh-ed25519 issuer=kubectl-ssh-oidc status=success details="user john.doe authenticated with ssh-ed25519 key"
      
    • Logs both successful authentications and failed attempts with detailed reasons
    • Includes username, SSH key identifier, issuer, and status for security monitoring
  • Principle of Least Privilege: Use RBAC to limit user permissions

🚦 Supported Platforms

Platform Architecture Status
Linux amd64 ✅ Supported
Linux arm64 ✅ Supported
macOS amd64 (Intel) ✅ Supported
macOS arm64 (Apple Silicon) ✅ Supported
Windows amd64 ✅ Supported

📊 Project Status

This project includes:

  • kubectl plugin: Complete OAuth2 Token Exchange implementation in pkg/kubectl/
  • Comprehensive tests: Unit tests and integration tests
  • Cross-platform builds: Automated build pipeline
  • Documentation: Usage examples and configuration guides
  • ⚠️ Binary releases: Set up GitHub Actions for automated releases

Dex SSH connector: Available in the separate fork at github.com/nikogura/dex

📋 Requirements

  • kubectl: v1.20+
  • Go: 1.21+ (for building from source)
  • SSH Keys: SSH agent or filesystem keys (OpenSSH format)
  • Dex: v2.39.1+ with custom SSH connector (see Usage.md for setup)
  • Kubernetes: v1.20+ with OIDC support configured

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

📞 Support


Made with ❤️ for the Kubernetes community

About

Passwordless Authentication to Kubernetes via SSH Keys

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors