Skip to content

[SECURITY] Production security logging with correlation IDs and audit trail - closes #55#84

Merged
sjackson0109 merged 15 commits into
sjackson0109:mainfrom
Ibrahim-3d:feat/55-production-logging
May 29, 2026
Merged

[SECURITY] Production security logging with correlation IDs and audit trail - closes #55#84
sjackson0109 merged 15 commits into
sjackson0109:mainfrom
Ibrahim-3d:feat/55-production-logging

Conversation

@Ibrahim-3d

@Ibrahim-3d Ibrahim-3d commented May 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Creates pt_security_logger.py as a standalone security event logging module (independent of pt_logging_system.py) providing security-specific event logging, correlation ID propagation, and a dedicated rotating audit log.

Changes

  • New: app/pt_security_logger.py
  • New: app/test_security_logger.py — 25 tests

Key features

Feature Detail
Correlation IDs CorrelationContext('cid') sets thread-local ID; CorrelationLogFilter injects into all records
Security events AUTH_ATTEMPT/SUCCESS/FAILURE, CREDENTIAL_USE/ROTATION, SUSPICIOUS_ACTIVITY, PERMISSION_DENIED, TRADE_EXECUTED/REJECTED, SYSTEM_START/STOP
Audit log Dedicated security_audit.jsonl, RotatingFileHandler (10MB/10 backups), owner-only permissions
Thread isolation Each thread has its own correlation ID (threading.local)

Usage

\\python
from pt_security_logger import security_logger, CorrelationContext

Propagate correlation ID through a workflow

with CorrelationContext('order-workflow-abc') as cid:
security_logger.log_auth_attempt('robinhood', success=True)
security_logger.log_trade_event('BTC-USD', 'buy', 0.1, 45000.0)

Suspicious activity alert

security_logger.log_suspicious_activity(
'rate_limit_exceeded', source_ip='1.2.3.4',
details={'endpoint': '/orders', 'count': 150}
)
\\

Test plan

  • 25 tests pass
  • Thread-local correlation ID isolation verified
  • Context manager restore/clear tested
  • All event types written and readable
  • Audit log rotation handler configured

Closes #55

Copilot AI review requested due to automatic review settings May 17, 2026 20:49
@Ibrahim-3d Ibrahim-3d requested a review from sjackson0109 as a code owner May 17, 2026 20:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a new security/audit logging module with correlation ID context support and accompanying unit tests.

Changes:

  • New pt_security_logger module providing SecurityLogger, SecurityEvent, SecurityEventType, and thread-local correlation ID utilities.
  • Dedicated rotating JSONL audit log with owner-only file permissions and a CorrelationLogFilter.
  • Comprehensive unit tests covering correlation context, event serialization, and security event logging.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 16 comments.

File Description
app/pt_security_logger.py New module implementing security audit logging, correlation IDs, and a module-level singleton.
app/test_security_logger.py Tests for correlation IDs, SecurityEvent, and SecurityLogger methods.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread app/pt_security_logger.py Outdated
Comment thread app/pt_security_logger.py Outdated
Comment thread app/pt_security_logger.py Outdated
Comment thread app/pt_security_logger.py Outdated
Comment thread app/pt_security_logger.py Outdated
Comment thread app/pt_security_logger.py Outdated
Comment thread app/pt_security_logger.py Outdated
Comment thread app/pt_security_logger.py Outdated
Comment thread app/pt_security_logger.py Outdated
Comment thread app/pt_security_logger.py Outdated
@sjackson0109 sjackson0109 self-assigned this May 17, 2026
@sjackson0109 sjackson0109 added logging component-security Security components component-monitoring Monitoring and observability components labels May 17, 2026
@Ibrahim-3d

Copy link
Copy Markdown
Collaborator Author

Local CI Simulation Results

Ran all workflow steps locally against this branch prior to owner approval. Results:

Code Quality & Testing

Check Tool Result
Code formatting black --check ✅ Pass — 0 files need reformatting
Import ordering isort --check ✅ Pass
Linting (hard errors) flake8 --select=E9,F63,F7,F82 ✅ Pass — 0 syntax/undefined-name errors
Linting (extended) flake8 --exit-zero ✅ Pass — 0 warnings in new files
Unit tests pytest ✅ All tests pass (see table below)

Unit Test Results

File Tests Result
test_circuit_breaker.py 20 ✅ All pass
test_credentials_rotation.py 30 ✅ All pass
test_error_handler.py 22 ✅ All pass
test_backup_validation.py 35 ✅ All pass
test_database_manager.py 29 ✅ All pass
test_security_logger.py 25 ✅ All pass

CI/CD Pipeline

Workflow Status Reason
Code Quality & Testing ⏳ Awaiting owner approval Fork PR — first-time contributor gate
PowerTrader AI+ CI/CD ⏳ Awaiting owner approval Fork PR — first-time contributor gate
Project Management ⏳ Awaiting owner approval Fork PR — first-time contributor gate

All three workflows are queued with action_required status. This is GitHub's security gate for PRs from fork contributors. Once approved by @sjackson0109, they will execute against the same code that was verified locally above.

Copilot AI review requested due to automatic review settings May 18, 2026 16:57

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 11 comments.

Comment thread app/test_security_logger.py Outdated
Comment thread app/pt_security_logger.py Outdated
Comment thread app/pt_security_logger.py Outdated
Comment thread app/pt_security_logger.py Outdated
Comment thread app/pt_security_logger.py Outdated
Comment thread app/pt_security_logger.py
Comment thread app/pt_security_logger.py
Comment thread app/pt_security_logger.py
Comment thread app/pt_security_logger.py Outdated
Comment thread app/pt_security_logger.py Outdated
…racking

pt_security_logger.py:
- SecurityLogger with RotatingFileHandler (10MB/10 backups), secure permissions,
  JSONL structured events
- SecurityEventType enum: auth, credential, suspicious, trade, system events
- correlation_context() thread-local context manager propagates request IDs
- CorrelationLogFilter injects correlation_id into all LogRecords
- Module-level security_logger singleton for application-wide use

- 25 unit tests, all passing
@Ibrahim-3d Ibrahim-3d force-pushed the feat/55-production-logging branch from 0e1e135 to 4645e27 Compare May 18, 2026 18:39
pt_security_logger.py:
- Module-level singleton is now lazy (get_security_logger()) — audit file
  not created at import time; default log_dir is ~/.powertraderai/logs,
  not the source tree; os.makedirs ensures dir exists before handler creation
- Per-instance logging.Logger (not global registry) eliminates the
  shared-handler/_handler=None pitfall when two instances share a log_dir
- _SecureRotatingFileHandler subclass overrides doRollover() to chmod
  active file and all backups after rotation
- _chmod_secure() called once at handler creation, not on every _emit();
  OSError logged as WARNING instead of silently swallowed
- correlation_context renamed to CorrelationContext (PEP 8 CapWords);
  snake_case alias kept for backwards compatibility
- CorrelationContext uses a _stack list so nested/reused instances are
  safe (no _previous corruption)
- clear_correlation_id() uses del instead of setting to None
- SecurityEvent.new_id() uses datetime.now(timezone.utc) for UTC IDs
- get_recent_events() uses collections.deque(f, maxlen=limit) for O(limit)
  tail read instead of readlines() O(file size)
- hashlib.md5 removed (per-instance logger needs no path hash)
- Added log_rate_limit() and log_config_change() helpers for enum values
  that previously had no public method
- Generator import removed (was unused)
- Docstring updated: module does NOT extend pt_logging_system

test_security_logger.py:
- tearDown uses sec_logger.close() to release file handles
- test_get_recent_events_empty_when_no_log: adds assertEqual([], ...) assertion
- test_get_recent_events_limit: asserts returned events are the last N
- Added test_new_id_uses_utc, test_context_manager_nested_safe,
  test_snake_case_alias_works, test_log_rate_limit, test_log_config_change
Copilot AI review requested due to automatic review settings May 19, 2026 08:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated 5 comments.

Comment thread app/pt_security_logger.py
Comment thread app/pt_security_logger.py Outdated
Comment thread app/pt_security_logger.py Outdated
Comment thread app/pt_security_logger.py Outdated
Comment thread app/test_security_logger.py Outdated
@Ibrahim-3d

Copy link
Copy Markdown
Collaborator Author

Manual Testing Guide — PR #84: Production Security Logging

Prerequisites

git fetch fork && git checkout feat/55-production-logging
cd app

1. Run unit tests

python -m pytest test_security_logger.py -v

Expected: All 25+ tests pass.

2. Smoke test — no file created at import time (key fix)

python -c "
import sys, os
# Record files in app/ before import
before = set(os.listdir('.'))
import pt_security_logger  # module import must NOT create security_audit.jsonl
after = set(os.listdir('.'))
new_files = after - before
print('new files on import:', new_files)
assert 'security_audit.jsonl' not in new_files, 'audit file created at import!'
print('PASS: no file created at import')
"

3. Smoke test — audit file goes to ~/.powertraderai/logs (key fix)

python -c "
import os, tempfile
from pt_security_logger import SecurityLogger

# Explicit log_dir
with tempfile.TemporaryDirectory() as d:
    sl = SecurityLogger(log_dir=d)
    sl.log_auth_attempt('binance', success=True)
    events = sl.get_recent_events()
    print('events logged:', len(events))
    assert len(events) == 1
    print('event_type:', events[0]['event_type'])
    sl.close()
print('PASS')
"

4. Verify correlation ID context nesting (key fix)

python -c "
from pt_security_logger import CorrelationContext, get_correlation_id, clear_correlation_id
import tempfile
clear_correlation_id()

ctx = CorrelationContext('outer')
with ctx:
    print('outer:', get_correlation_id())  # outer
    with ctx:
        print('nested:', get_correlation_id())  # outer (same instance reused safely)
    print('after inner exit:', get_correlation_id())  # outer
print('after outer exit:', get_correlation_id())  # None
print('PASS')
"

5. Verify rate_limit and config_change helpers exist (key fix)

python -c "
import tempfile
from pt_security_logger import SecurityLogger, SecurityEventType

with tempfile.TemporaryDirectory() as d:
    sl = SecurityLogger(log_dir=d)
    sl.log_rate_limit('robinhood', details={'endpoint': '/orders'})
    sl.log_config_change('risk_limits', details={'max_pos': 0.05})
    events = sl.get_recent_events()
    types = [e['event_type'] for e in events]
    print('event types:', types)
    assert SecurityEventType.RATE_LIMIT.value in types
    assert SecurityEventType.CONFIG_CHANGE.value in types
    sl.close()
print('PASS')
"

6. Verify audit file permissions (Unix only)

python -c "
import tempfile, stat, os
from pt_security_logger import SecurityLogger
with tempfile.TemporaryDirectory() as d:
    sl = SecurityLogger(log_dir=d)
    sl.log_auth_attempt('test', success=True)
    mode = oct(stat.S_IMODE(os.stat(sl._audit_path).st_mode))
    print('permissions:', mode)  # should be 0o600
    sl.close()
"

Expected on Unix: 0o600 (owner read/write only).

Rollback

git checkout main -- app/pt_security_logger.py app/test_security_logger.py

- Remove unused hashlib import
- close(): make idempotent by clearing self._handler after shutdown
- get_recent_events: guard limit <= 0 (deque maxlen rejects negatives);
  docstring corrected to reflect O(file_size) time / O(limit) memory
- test_multiple_events_ordered: assert event_type append order (robust to
  clock adjustments) + non-decreasing timestamp sanity check
Copilot AI review requested due to automatic review settings May 20, 2026 13:48
@Ibrahim-3d

Copy link
Copy Markdown
Collaborator Author

All 23 outstanding Copilot threads resolved. Round-1/2 threads (already replied inline) marked resolved; round-3 (5 new) addressed in commit 08dd045:

  • deque negative limit: get_recent_events now guards limit <= 0 and returns [] before constructing the deque.
  • docstring time complexity: corrected to O(file_size) time / O(limit) memory.
  • close() idempotent: handler reference cleared after shutdown; safe to call multiple times.
  • unused hashlib: removed.
  • non-monotonic timestamps in test: ordering now asserted on event_type sequence (robust to NTP/DST); non-decreasing timestamp kept as cheap sanity check.

All 30 test_security_logger tests pass locally. Ready for re-review.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@Ibrahim-3d

Copy link
Copy Markdown
Collaborator Author

@sjackson0109 all 23 outstanding Copilot threads cleared (5 round-3 fixed in 08dd045, 18 round-1/2 resolved). 30 tests pass. Ready for re-review.

Copilot AI review requested due to automatic review settings May 21, 2026 14:01
@Ibrahim-3d Ibrahim-3d force-pushed the feat/55-production-logging branch from 637b547 to 98cfa3c Compare May 21, 2026 14:01

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copilot AI review requested due to automatic review settings May 24, 2026 21:07
sjackson0109
sjackson0109 previously approved these changes May 24, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 5 comments.

Comment thread app/pt_security_logger.py Outdated
Comment thread app/pt_security_logger.py
Comment thread app/pt_security_logger.py Outdated
Comment thread app/pt_security_logger.py
Comment thread app/pt_security_logger.py Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.

Comment thread app/pt_security_logger.py Outdated
Comment thread app/pt_security_logger.py Outdated
…gging

# Conflicts:
#	app/pt_security_logger.py
@Ibrahim-3d

Copy link
Copy Markdown
Collaborator Author

Copilot review follow-up (commit 5f96c43)

Merged main to clear the conflict and addressed all open threads:

# File:Line Issue Resolution
1 pt_security_logger.py:50 AUTH_ATTEMPT defined but never emitted Removed dead enum value; test repointed to AUTH_SUCCESS
2 pt_security_logger.py:close() close() not synchronized with _emit() close() now holds self._lock (same lock as _emit), stays idempotent
3 pt_security_logger.py:get_recent_events() Malformed JSON lines silently dropped Lines still skipped but counted and surfaced via logger.warning
4 pt_security_logger.py:log_system_event() Docstring implied a closed event-type set Docstring now states any SecurityEventType is accepted; examples illustrative
5 pt_security_logger.py:50 Duplicate of #1 Same fix
6 pt_security_logger.py:12 'extends pt_logging_system' vs standalone Took main's wording (#98/#99); module documented as fully self-contained

Black + flake8 clean, 30 unit tests pass.

@Ibrahim-3d Ibrahim-3d closed this May 26, 2026
@Ibrahim-3d Ibrahim-3d reopened this May 26, 2026
Copilot AI review requested due to automatic review settings May 26, 2026 19:24

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.

Comment thread app/pt_security_logger.py
Copilot AI review requested due to automatic review settings May 27, 2026 08:05

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.

Comment thread app/pt_security_logger.py
@Ibrahim-3d

Copy link
Copy Markdown
Collaborator Author

@sjackson0109 I have updated the PR description to correctly state that pt_security_logger is a standalone module and does not depend on pt_logging_system. I also updated the usage examples in the description to use CorrelationContext for consistency with the code. This addresses the documentation mismatch flagged by Copilot.

@Ibrahim-3d

Copy link
Copy Markdown
Collaborator Author

@copilot do final review

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.

Comment thread app/pt_security_logger.py
Comment thread app/pt_security_logger.py
@sjackson0109 sjackson0109 merged commit 95aa2b0 into sjackson0109:main May 29, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component-monitoring Monitoring and observability components component-security Security components logging

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[SECURITY] Implement production-grade logging system

3 participants