slack-rs 0.1.70

A Slack CLI tool with OAuth authentication, profile management, and API access
Documentation
# Security Specification

## Overview
This document defines security measures to prevent accidental data exposure and destructive operations.

## Token Protection

### Storage
- **NEVER** store tokens in plaintext files
- **ALWAYS** use OS file storage (macOS file storage, Windows Credential Manager, Linux Secret Service)
- Config file (`profiles.json`) must contain only non-secret metadata

### Logging
- **NEVER** log tokens in any form
- Mask `Authorization` headers in debug logs:
  - Before: `Authorization: Bearer xoxp-1234567890-abcdefghij`
  - After: `Authorization: Bearer xoxp-****`
- Mask tokens in error messages:
  - Before: `Failed to authenticate with token xoxp-1234567890`
  - After: `Failed to authenticate with token xoxp-****`

### Output
- **NEVER** include tokens in JSON or text output
- API responses should not echo the token used

## Write Operation Safety

### Two-Tier Protection

#### Tier 1: `--allow-write` Flag (Required for all writes)
- **Scope**: All write operations (`msg post/update/delete`, `react add/remove`)
- **Enforcement**: Check at command execution time
- **Error if missing**:
  ```
  Error: Write operations require --allow-write flag.
  Example: slack-rs --profile myworkspace --allow-write msg post --channel C123 --text "Hello"
  ```
- **Exit code**: 1

#### Tier 2: `--yes` Flag (Required for destructive operations)
- **Scope**: Destructive operations only (`msg delete`, future: `files delete`, etc.)
- **Enforcement**: Check after `--allow-write` validation
- **Behavior if missing**:
  - Display confirmation prompt (localized):
    ```
    You are about to delete a message:
      Channel: #general (C123ABC)
      Timestamp: 1234567890.123456
    
    This action cannot be undone. Continue? [y/N]:
    ```
  - If user enters `y` or `yes` (case-insensitive): proceed
  - Otherwise: abort with exit code 1
- **With `--yes` flag**: Skip prompt, execute immediately

### Implementation Pattern

```rust
fn execute_write_command(allow_write: bool, needs_confirmation: bool, yes: bool) -> Result<()> {
    // Tier 1: Check --allow-write
    if !allow_write {
        return Err(Error::WriteNotAllowed);
    }
    
    // Tier 2: Check confirmation for destructive ops
    if needs_confirmation && !yes {
        if !prompt_user_confirmation()? {
            return Err(Error::OperationCancelled);
        }
    }
    
    // Proceed with operation
    Ok(())
}
```

## Profile Confusion Prevention

### Mandatory `--profile` Flag
- **All API-hitting commands** require explicit `--profile` specification
- **No default profile** (prevents accidental operations on wrong workspace)
- **Error if missing**:
  ```
  Error: --profile is required.
  Run 'slack-rs auth list' to see available profiles.
  ```

### Output Context
- **All JSON responses** must include profile context:
  ```json
  {
    "meta": {
      "profile_name": "acme-work",
      "team_id": "T123ABC",
      "team_name": "Acme Corp",
      "user_id": "U456DEF"
    },
    "data": { ... }
  }
  ```
- **Text output** must show workspace identifier:
  ```
  [acme-work / Acme Corp] Message posted successfully
  ```

## Rate Limiting Protection

### Respect Slack Limits
- Honor HTTP 429 responses
- Parse `Retry-After` header (seconds)
- Wait before retrying

### Exponential Backoff
- Initial retry delay: 1 second
- Multiply by 2 on each retry (with jitter)
- Maximum retry delay: 60 seconds
- Maximum retry attempts: 5

### Jitter Formula
```rust
let jitter = rand::random::<f64>() * 0.3; // ±30%
let delay = base_delay * (1.0 + jitter);
```

## Input Validation

### Channel IDs
- Must match pattern: `^[CDG][A-Z0-9]{8,}$`
- Reject invalid formats early

### Timestamps
- Must match pattern: `^\d{10}\.\d{6}$`
- Example: `1234567890.123456`

### User IDs
- Must match pattern: `^[UW][A-Z0-9]{8,}$`

### Emoji Names
- Must match pattern: `^:[a-z0-9_+-]+:$`
- Example: `:white_check_mark:`

## Error Message Guidelines

### Do Not Expose Sensitive Data
- ❌ Bad: `Failed to post to channel C123ABC with token xoxp-1234567890`
- ✅ Good: `Failed to post to channel C123ABC: missing_scope`

### Provide Actionable Guidance
- ❌ Bad: `Error: 403`
- ✅ Good: `Error: Insufficient permissions. Required scope: chat:write. Run 'slack-rs auth status --profile myworkspace' to check current scopes.`

### Localize User-Facing Messages
- Error messages, prompts, and instructions should respect `--lang` flag
- API error codes remain in English (e.g., `missing_scope`, `channel_not_found`)

## Audit Trail (Future Enhancement)
- Optional audit log for write operations
- Format: JSON lines
- Fields: timestamp, profile, command, channel, result
- Location: `~/.local/share/slack-rs/audit.log`
- Disabled by default; enable with `SLACKRS_AUDIT=1`