# SSH Temporal Keys - User Guide

## Quick Start

### Generate and Connect with Temporary Key

The fastest way to use temporal SSH keys:

```bash
# Auto-generate, deploy, and connect (key auto-revoked after disconnect)
ssh connect server.example.com

# Connect with custom user and TTL
ssh connect server.example.com --user deploy --ttl 30 min

# Keep key active after disconnect
ssh connect server.example.com --keep
```plaintext

### Manual Key Management

For more control over the key lifecycle:

```bash
# 1. Generate key
ssh generate-key server.example.com --user root --ttl 1hr

# Output:
# ✓ SSH key generated successfully
#   Key ID: abc-123-def-456
#   Type: dynamickeypair
#   User: root
#   Server: server.example.com
#   Expires: 2024-01-01T13:00:00Z
#   Fingerprint: SHA256:...
#
# Private Key (save securely):
# -----BEGIN OPENSSH PRIVATE KEY-----
# ...
# -----END OPENSSH PRIVATE KEY-----

# 2. Deploy key to server
ssh deploy-key abc-123-def-456

# 3. Use the private key to connect
ssh -i /path/to/private/key root@server.example.com

# 4. Revoke when done
ssh revoke-key abc-123-def-456
```plaintext

## Key Features

### Automatic Expiration

All keys expire automatically after their TTL:

- **Default TTL**: 1 hour
- **Configurable**: From 5 minutes to 24 hours
- **Background Cleanup**: Automatic removal from servers every 5 minutes

### Multiple Key Types

Choose the right key type for your use case:

| Type | Description | Use Case |
|------|-------------|----------|
| **dynamic** (default) | Generated Ed25519 keys | Quick SSH access |
| **ca** | Vault CA-signed certificate | Enterprise with SSH CA |
| **otp** | Vault one-time password | Single-use access |

### Security Benefits

✅ No static SSH keys to manage
✅ Short-lived credentials (1 hour default)
✅ Automatic cleanup on expiration
✅ Audit trail for all operations
✅ Private keys never stored on disk

## Common Usage Patterns

### Development Workflow

```bash
# Quick SSH for debugging
ssh connect dev-server.local --ttl 30 min

# Execute commands
ssh root@dev-server.local "systemctl status nginx"

# Connection closes, key auto-revokes
```plaintext

### Production Deployment

```bash
# Generate key with longer TTL for deployment
ssh generate-key prod-server.example.com --ttl 2hr

# Deploy to server
ssh deploy-key <key-id>

# Run deployment script
ssh -i /tmp/deploy-key root@prod-server.example.com < deploy.sh

# Manual revoke when done
ssh revoke-key <key-id>
```plaintext

### Multi-Server Access

```bash
# Generate one key
ssh generate-key server01.example.com --ttl 1hr

# Use the same private key for multiple servers (if you have provisioning access)
# Note: Currently each key is server-specific, multi-server support coming soon
```plaintext

## Command Reference

### ssh generate-key

Generate a new temporal SSH key.

**Syntax**:

```bash
ssh generate-key <server> [options]
```plaintext

**Options**:

- `--user <name>`: SSH user (default: root)
- `--ttl <duration>`: Key lifetime (default: 1hr)
- `--type <ca|otp|dynamic>`: Key type (default: dynamic)
- `--ip <address>`: Allowed IP (OTP mode only)
- `--principal <name>`: Principal (CA mode only)

**Examples**:

```bash
# Basic usage
ssh generate-key server.example.com

# Custom user and TTL
ssh generate-key server.example.com --user deploy --ttl 30 min

# Vault CA mode
ssh generate-key server.example.com --type ca --principal admin
```plaintext

### ssh deploy-key

Deploy a generated key to the target server.

**Syntax**:

```bash
ssh deploy-key <key-id>
```plaintext

**Example**:

```bash
ssh deploy-key abc-123-def-456
```plaintext

### ssh list-keys

List all active SSH keys.

**Syntax**:

```bash
ssh list-keys [--expired]
```plaintext

**Examples**:

```bash
# List active keys
ssh list-keys

# Show only deployed keys
ssh list-keys | where deployed == true

# Include expired keys
ssh list-keys --expired
```plaintext

### ssh get-key

Get detailed information about a specific key.

**Syntax**:

```bash
ssh get-key <key-id>
```plaintext

**Example**:

```bash
ssh get-key abc-123-def-456
```plaintext

### ssh revoke-key

Immediately revoke a key (removes from server and tracking).

**Syntax**:

```bash
ssh revoke-key <key-id>
```plaintext

**Example**:

```bash
ssh revoke-key abc-123-def-456
```plaintext

### ssh connect

Auto-generate, deploy, connect, and revoke (all-in-one).

**Syntax**:

```bash
ssh connect <server> [options]
```plaintext

**Options**:

- `--user <name>`: SSH user (default: root)
- `--ttl <duration>`: Key lifetime (default: 1hr)
- `--type <ca|otp|dynamic>`: Key type (default: dynamic)
- `--keep`: Don't revoke after disconnect

**Examples**:

```bash
# Quick connection
ssh connect server.example.com

# Custom user
ssh connect server.example.com --user deploy

# Keep key active after disconnect
ssh connect server.example.com --keep
```plaintext

### ssh stats

Show SSH key statistics.

**Syntax**:

```bash
ssh stats
```plaintext

**Example Output**:

```plaintext
SSH Key Statistics:
  Total generated: 42
  Active keys: 10
  Expired keys: 32

Keys by type:
  dynamic: 35
  otp: 5
  certificate: 2

Last cleanup: 2024-01-01T12:00:00Z
  Cleaned keys: 5
```plaintext

### ssh cleanup

Manually trigger cleanup of expired keys.

**Syntax**:

```bash
ssh cleanup
```plaintext

### ssh test

Run a quick test of the SSH key system.

**Syntax**:

```bash
ssh test <server> [--user <name>]
```plaintext

**Example**:

```bash
ssh test server.example.com --user root
```plaintext

### ssh help

Show help information.

**Syntax**:

```bash
ssh help
```plaintext

## Duration Formats

The `--ttl` option accepts various duration formats:

| Format | Example | Meaning |
|--------|---------|---------|
| Minutes | `30 min` | 30 minutes |
| Hours | `2hr` | 2 hours |
| Mixed | `1hr 30 min` | 1.5 hours |
| Seconds | `3600sec` | 1 hour |

## Working with Private Keys

### Saving Private Keys

When you generate a key, save the private key immediately:

```bash
# Generate and save to file
ssh generate-key server.example.com | get private_key | save -f ~/.ssh/temp_key
chmod 600 ~/.ssh/temp_key

# Use the key
ssh -i ~/.ssh/temp_key root@server.example.com

# Cleanup
rm ~/.ssh/temp_key
```plaintext

### Using SSH Agent

Add the temporary key to your SSH agent:

```bash
# Generate key and extract private key
ssh generate-key server.example.com | get private_key | save -f /tmp/temp_key
chmod 600 /tmp/temp_key

# Add to agent
ssh-add /tmp/temp_key

# Connect (agent provides the key automatically)
ssh root@server.example.com

# Remove from agent
ssh-add -d /tmp/temp_key
rm /tmp/temp_key
```plaintext

## Troubleshooting

### Key Deployment Fails

**Problem**: `ssh deploy-key` returns error

**Solutions**:

1. Check SSH connectivity to server:

   ```bash
   ssh root@server.example.com
   ```

1. Verify provisioning key is configured:

   ```bash
   echo $PROVISIONING_SSH_KEY
   ```

2. Check server SSH daemon:

   ```bash
   ssh root@server.example.com "systemctl status sshd"
   ```

### Private Key Not Working

**Problem**: SSH connection fails with "Permission denied (publickey)"

**Solutions**:

1. Verify key was deployed:

   ```bash
   ssh list-keys | where id == "<key-id>"
   ```

2. Check key hasn't expired:

   ```bash
   ssh get-key <key-id> | get expires_at
   ```

3. Verify private key permissions:

   ```bash
   chmod 600 /path/to/private/key
   ```

### Cleanup Not Running

**Problem**: Expired keys not being removed

**Solutions**:

1. Check orchestrator is running:

   ```bash
   curl http://localhost:9090/health
   ```

2. Trigger manual cleanup:

   ```bash
   ssh cleanup
   ```

3. Check orchestrator logs:

   ```bash
   tail -f ./data/orchestrator.log | grep SSH
   ```

## Best Practices

### Security

1. **Short TTLs**: Use the shortest TTL that works for your task

   ```bash
   ssh connect server.example.com --ttl 30 min
   ```

2. **Immediate Revocation**: Revoke keys when you're done

   ```bash
   ssh revoke-key <key-id>
   ```

3. **Private Key Handling**: Never share or commit private keys

   ```bash
   # Save to temp location, delete after use
   ssh generate-key server.example.com | get private_key | save -f /tmp/key
   # ... use key ...
   rm /tmp/key
   ```

### Workflow Integration

1. **Automated Deployments**: Generate key in CI/CD

   ```bash
   #!/bin/bash
   KEY_ID=$(ssh generate-key prod.example.com --ttl 1hr | get id)
   ssh deploy-key $KEY_ID
   # Run deployment
   ansible-playbook deploy.yml
   ssh revoke-key $KEY_ID
   ```

2. **Interactive Use**: Use `ssh connect` for quick access

   ```bash
   ssh connect dev.example.com
   ```

3. **Monitoring**: Check statistics regularly

   ```bash
   ssh stats
   ```

## Advanced Usage

### Vault Integration

If your organization uses HashiCorp Vault:

#### CA Mode (Recommended)

```bash
# Generate CA-signed certificate
ssh generate-key server.example.com --type ca --principal admin --ttl 1hr

# Vault signs your public key
# Server must trust Vault CA certificate
```plaintext

**Setup** (one-time):

```bash
# On servers, add to /etc/ssh/sshd_config:
TrustedUserCAKeys /etc/ssh/trusted-user-ca-keys.pem

# Get Vault CA public key:
vault read -field=public_key ssh/config/ca | \
  sudo tee /etc/ssh/trusted-user-ca-keys.pem

# Restart SSH:
sudo systemctl restart sshd
```plaintext

#### OTP Mode

```bash
# Generate one-time password
ssh generate-key server.example.com --type otp --ip 192.168.1.100

# Use the OTP to connect (single use only)
```plaintext

### Scripting

Use in scripts for automated operations:

```nushell
# deploy.nu
def deploy [target: string] {
    let key = (ssh generate-key $target --ttl 1hr)
    ssh deploy-key $key.id

    # Run deployment
    try {
        ssh $"root@($target)" "bash /path/to/deploy.sh"
    } catch {
        print "Deployment failed"
    }

    # Always cleanup
    ssh revoke-key $key.id
}
```plaintext

## API Integration

For programmatic access, use the REST API:

```bash
# Generate key
curl -X POST http://localhost:9090/api/v1/ssh/generate \
  -H "Content-Type: application/json" \
  -d '{
    "key_type": "dynamickeypair",
    "user": "root",
    "target_server": "server.example.com",
    "ttl_seconds": 3600
  }'

# Deploy key
curl -X POST http://localhost:9090/api/v1/ssh/{key_id}/deploy

# List keys
curl http://localhost:9090/api/v1/ssh/keys

# Get stats
curl http://localhost:9090/api/v1/ssh/stats
```plaintext

## FAQ

**Q: Can I use the same key for multiple servers?**
A: Currently, each key is tied to a specific server. Multi-server support is planned.

**Q: What happens if the orchestrator crashes?**
A: Keys in memory are lost, but keys already deployed to servers remain until their expiration time.

**Q: Can I extend the TTL of an existing key?**
A: No, you must generate a new key. This is by design for security.

**Q: What's the maximum TTL?**
A: Configurable by admin, default maximum is 24 hours.

**Q: Are private keys stored anywhere?**
A: Private keys exist only in memory during generation and are shown once to the user. They are never written to disk by the system.

**Q: What happens if cleanup fails?**
A: The key remains in authorized_keys until the next cleanup run. You can trigger manual cleanup with `ssh cleanup`.

**Q: Can I use this with non-root users?**
A: Yes, use `--user <username>` when generating the key.

**Q: How do I know when my key will expire?**
A: Use `ssh get-key <key-id>` to see the exact expiration timestamp.

## Support

For issues or questions:

1. Check orchestrator logs: `tail -f ./data/orchestrator.log`
2. Run diagnostics: `ssh stats`
3. Test connectivity: `ssh test server.example.com`
4. Review documentation: `SSH_KEY_MANAGEMENT.md`

## See Also

- **Architecture**: `SSH_KEY_MANAGEMENT.md`
- **Implementation**: `SSH_IMPLEMENTATION_SUMMARY.md`
- **Configuration**: `config/ssh-config.toml.example`
