# Story 4.29: Audit Encryption Configuration Accuracy

**Status:** Complete
**Priority:** High
**Depends on:** None

---

## Context / Background

The GPT-5.2 audit identified a critical mismatch between configuration and behavior: `CompliancePolicy.encrypt_audit_logs` defaults to `True`, but the actual `_store_event` implementation writes plaintext JSONL with no encryption.

**Current state in `src/fapilog/core/audit.py`:**

```python
@dataclass
class CompliancePolicy:
    # ...
    encrypt_audit_logs: bool = True  # Claims encryption by default
```

But in `_store_event`:
```python
with open(log_file, "a", encoding="utf-8") as f:
    f.write(json_line + "\n")  # Plaintext write, no encryption
```

**Problem:**
- Configuration implies encryption is enabled by default
- Users may rely on this for compliance (HIPAA, SOX, etc.)
- Actual behavior provides no encryption
- This is a compliance risk and trust issue

**Options:**
1. **Implement encryption** - Significant effort, adds cryptography dependency
2. **Change default to False** - Honest about current capability
3. **Remove the setting** - Until encryption is implemented

This story takes approach #2 (change default + document) as the pragmatic fix, with encryption implementation deferred to a future story.

---

## Scope (In / Out)

### In Scope

- Change `encrypt_audit_logs` default from `True` to `False`
- Add runtime warning if `encrypt_audit_logs=True` (not implemented)
- Document that encryption is planned but not yet implemented
- Update any documentation that implies encryption works

### Out of Scope

- Actually implementing encryption (future story 4.30+)
- Changing hash-chain integrity (that works correctly)
- fapilog-tamper package changes (separate add-on)

---

## Acceptance Criteria

### AC1: Default Changed to False

**Description:** `CompliancePolicy.encrypt_audit_logs` defaults to `False`.

**Validation:**
```python
from fapilog.core.audit import CompliancePolicy

policy = CompliancePolicy()
assert policy.encrypt_audit_logs is False
```

### AC2: Warning Emitted When True

**Description:** If user explicitly sets `encrypt_audit_logs=True`, a warning is emitted.

**Validation:**
```python
import warnings
from fapilog.core.audit import AuditTrail, CompliancePolicy

with warnings.catch_warnings(record=True) as w:
    warnings.simplefilter("always")
    policy = CompliancePolicy(encrypt_audit_logs=True)
    trail = AuditTrail(policy=policy)

    assert len(w) == 1
    assert "not yet implemented" in str(w[0].message).lower()
```

### AC3: AuditSinkConfig Also Updated

**Description:** `AuditSinkConfig.encrypt_logs` in `plugins/sinks/audit.py` also defaults to `False`.

**Validation:**
```python
from fapilog.plugins.sinks.audit import AuditSinkConfig

config = AuditSinkConfig()
assert config.encrypt_logs is False
```

### AC4: Documentation Updated

**Description:** Any docs mentioning audit encryption clarify it's planned but not implemented.

**Validation:**
- Review `docs/` for encryption mentions
- Ensure they note current status

---

## Implementation Notes

### File Changes

```
src/fapilog/core/audit.py (MODIFIED - change default, add warning)
src/fapilog/plugins/sinks/audit.py (MODIFIED - change default)
docs/user-guide/reliability-defaults.md (MODIFIED - clarify status)
tests/unit/test_audit_encryption_warning.py (NEW)
```

### Key Code Changes

```python
# src/fapilog/core/audit.py

@dataclass
class CompliancePolicy:
    # ...
    encrypt_audit_logs: bool = False  # Changed from True
```

```python
# src/fapilog/core/audit.py - in AuditTrail.__init__

def __init__(
    self,
    policy: Optional[CompliancePolicy] = None,
    storage_path: Optional[Path] = None,
) -> None:
    self.policy = policy or CompliancePolicy()

    # Warn if encryption requested but not implemented
    if self.policy.encrypt_audit_logs:
        import warnings
        warnings.warn(
            "encrypt_audit_logs=True requested but encryption is not yet "
            "implemented. Audit logs will be written as plaintext JSONL with "
            "hash-chain integrity. See docs for encryption roadmap.",
            UserWarning,
            stacklevel=2,
        )
    # ...
```

---

## Tasks

### Phase 1: Core Changes

- [ ] Change `CompliancePolicy.encrypt_audit_logs` default to `False`
- [ ] Add warning in `AuditTrail.__init__` when True
- [ ] Change `AuditSinkConfig.encrypt_logs` default to `False`
- [ ] Add warning in audit sink when encrypt_logs=True

### Phase 2: Testing

- [ ] Add test for new default value
- [ ] Add test for warning emission
- [ ] Verify existing tests still pass

### Phase 3: Documentation

- [ ] Update reliability-defaults.md
- [ ] Add note about encryption roadmap
- [ ] Update CHANGELOG

---

## Tests

### Unit Tests

- `tests/unit/test_audit_encryption_warning.py`
  - `test_default_encrypt_audit_logs_is_false`
  - `test_warning_when_encrypt_true`
  - `test_no_warning_when_encrypt_false`

### Existing Tests

- All existing audit tests should pass unchanged

---

## Definition of Done

### Code Complete

- [x] Default changed to False
- [x] Warning emitted when True
- [x] Both core and sink configs updated

### Quality Assurance

- [x] All tests pass
- [x] `ruff check` passes
- [x] `mypy` passes

### Documentation

- [x] User docs updated
- [ ] CHANGELOG updated
- [ ] Roadmap for encryption documented

---

## Risks / Rollback

### Risks

1. **Risk:** Users relying on assumed encryption
   - **Mitigation:** This change makes the truth explicit; better than false assurance

2. **Risk:** Breaking existing configurations
   - **Mitigation:** Warning provides migration path; behavior unchanged

### Rollback Plan

If issues occur:
1. Revert default change
2. Add more prominent documentation instead

---

## Related Stories

- **Enables:** Future Story 4.30+ - Actual encryption implementation
- **Related:** Story 4.11 - Audit integrity HMAC (integrity, not encryption)
- **Related:** fapilog-tamper package (separate encryption approach)

---

## Change Log

| Date | Change | Author |
|------|--------|--------|
| 2026-01-16 | Initial draft from GPT-5.2 audit | Claude |
