Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,3 +216,55 @@ troubleshoot-demo-003 Ready <none> 2d21h v1.23.5
bash-5.0$ exit
exit
```

## Authentication

sbctl supports optional token-based authentication to secure kubectl commands connecting to the local API server.

**Note:** Enabling authentication automatically enables HTTPS with self-signed certificates. This is required because kubectl refuses to send credentials over unencrypted HTTP connections.

### Runtime Authentication

Enable authentication at runtime using the `--enable-auth` flag:

```bash
sbctl serve --enable-auth ~/Downloads/support-bundle-2024-XX-XX

Server is running

Authentication is enabled

export KUBECONFIG=/var/folders/.../T/local-kubeconfig-XXXXX
```

The generated token and TLS certificate are automatically included in the kubeconfig file, so kubectl commands will work seamlessly.

### Compile-Time Authentication Enforcement

For environments requiring mandatory authentication, build sbctl with the `auth_required` build tag:

```bash
go build -tags auth_required -o sbctl sbctl.go
```

When built with this tag, authentication is always enabled regardless of the `--enable-auth` flag.

### Security Features

- **HTTPS with TLS**: Self-signed certificates auto-generated for each session (24-hour validity)
- **256-bit tokens**: Cryptographically secure random tokens using `crypto/rand`
- **Bearer token standard**: Compatible with OAuth 2.0 conventions
- **Constant-time comparison**: Prevents timing attacks during token validation
- **Localhost-only**: Server binds to 127.0.0.1 for additional security
- **All endpoints protected**: No exemptions - every API endpoint requires authentication

### Authentication with Shell Mode

The `shell` command also supports the `--enable-auth` flag:

```bash
sbctl shell --enable-auth ~/Downloads/support-bundle-2024-XX-XX

Authentication is enabled
Starting new shell with KUBECONFIG. Press Ctl-D when done to exit from the shell and stop sbctl server
```
22 changes: 20 additions & 2 deletions cli/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,31 @@ func ServeCmd() *cobra.Command {
return nil
}

kubeConfig, err = api.StartAPIServer(clusterData, os.Stderr)
// Generate auth token and TLS certificate if required or enabled
var authToken string
var tlsCert *api.TLSCertificate
if api.AuthRequired || v.GetBool("enable-auth") {
authToken, err = api.GenerateToken()
if err != nil {
return errors.Wrap(err, "failed to generate auth token")
}

tlsCert, err = api.GenerateSelfSignedCert()
if err != nil {
return errors.Wrap(err, "failed to generate TLS certificate")
}
}

kubeConfig, err = api.StartAPIServer(clusterData, os.Stderr, authToken, tlsCert)
if err != nil {
return errors.Wrap(err, "failed to create api server")

}
defer os.RemoveAll(kubeConfig)

fmt.Printf("Server is running\n\n")
if authToken != "" {
fmt.Printf("Authentication is enabled\n\n")
}
fmt.Printf("export KUBECONFIG=%s\n\n", kubeConfig)

<-make(chan struct{})
Expand All @@ -120,6 +137,7 @@ func ServeCmd() *cobra.Command {

cmd.Flags().StringP("support-bundle-location", "s", "", "path to support bundle archive, directory, or URL")
cmd.Flags().StringP("token", "t", "", "API token for authentication when fetching on-line bundles")
cmd.Flags().Bool("enable-auth", false, "enable token-based authentication for kubectl commands")
cmd.Flags().Bool("debug", false, "enable debug logging. This will include HTTP response bodies in logs.")
return cmd
}
Expand Down
26 changes: 23 additions & 3 deletions cli/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import (
func ShellCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "shell",
Short: "Start interractive shell",
Long: `Start interractive shell`,
Short: "Start interactive shell",
Long: `Start interactive shell`,
Args: cobra.MaximumNArgs(1),
SilenceUsage: true,
SilenceErrors: false,
Expand Down Expand Up @@ -132,12 +132,31 @@ func ShellCmd() *cobra.Command {
return startShellAndWait(cdCmd)
}

kubeConfig, err = api.StartAPIServer(clusterData, logOutput)
// Generate auth token and TLS certificate if required or enabled
var authToken string
var tlsCert *api.TLSCertificate
if api.AuthRequired || v.GetBool("enable-auth") {
authToken, err = api.GenerateToken()
if err != nil {
return errors.Wrap(err, "failed to generate auth token")
}

tlsCert, err = api.GenerateSelfSignedCert()
if err != nil {
return errors.Wrap(err, "failed to generate TLS certificate")
}
}

kubeConfig, err = api.StartAPIServer(clusterData, logOutput, authToken, tlsCert)
if err != nil {
return errors.Wrap(err, "failed to create api server")
}
defer os.RemoveAll(kubeConfig)

if authToken != "" {
fmt.Printf("Authentication is enabled\n")
}

cmds := []string{
fmt.Sprintf("export KUBECONFIG=%s", kubeConfig),
}
Expand All @@ -158,6 +177,7 @@ func ShellCmd() *cobra.Command {

cmd.Flags().StringP("support-bundle-location", "s", "", "path to support bundle archive, directory, or URL")
cmd.Flags().StringP("token", "t", "", "API token for authentication when fetching on-line bundles")
cmd.Flags().Bool("enable-auth", false, "enable token-based authentication for kubectl commands")
cmd.Flags().Bool("cd-bundle", false, "Change directory to the support bundle path after starting the shell")
cmd.Flags().Bool("debug", false, "enable debug logging. This will include HTTP response bodies in logs.")
cmd.Flags().StringP("command", "c", "", "Run a command in the shell instead of starting an interactive session")
Expand Down
8 changes: 8 additions & 0 deletions pkg/api/auth_optional.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//go:build !auth_required
// +build !auth_required

package api

// AuthRequired indicates whether authentication is required at compile time.
// This file is included when the auth_required build tag is NOT set.
const AuthRequired = false
9 changes: 9 additions & 0 deletions pkg/api/auth_required.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//go:build auth_required
// +build auth_required

package api

// AuthRequired indicates whether authentication is required at compile time.
// This file is included when the auth_required build tag IS set.
// Build with: go build -tags auth_required
const AuthRequired = true
Loading
Loading