Skip to content

Commit 31101f8

Browse files
authored
Merge pull request #420 from wpengine/chore-wpgraphql-logging-data-management
chore: WPGraphQL Logging Data Management
2 parents 6b420ce + 228692e commit 31101f8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1363
-317
lines changed

.changeset/afraid-lobsters-hang.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@wpengine/wpgraphql-logging-wordpress-plugin": patch
3+
---
4+
5+
chore: Added data management for the logging plugin.

plugins/wpgraphql-logging/README.md

Lines changed: 129 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ wpgraphql-logging/
9191
│ ├── Admin/ # Admin settings, menu, and settings page logic
9292
│ ├── Settings/ # Admin settings functionality for displaying and saving data.
9393
│ ├── Events/ # Event logging, pub/sub event manager for extending the logging.
94-
│ ├── Logging/ # Logging logic, logger service, Monolog handlers & processors
94+
│ ├── Logger/ # Logging logic, logger service, Monolog handlers & processors
95+
│ ├── Rules/ # Rule Management on whether we log a query
96+
│ ├── Scheduler/ # Automated data cleanup and maintenance tasks
9597
│ ├── Plugin.php # Main plugin class (entry point)
9698
│ └── Autoload.php # PSR-4 autoloader
9799
├── tests/ # All test suites
@@ -119,6 +121,12 @@ wpgraphql-logging/
119121
- **Monolog-powered logging pipeline**
120122
- Default handler: stores logs in a WordPress table (`{$wpdb->prefix}wpgraphql_logging`).
121123

124+
- **Automated data management**
125+
- **Daily cleanup scheduler**: Automatically removes old logs based on retention settings.
126+
- **Configurable retention period**: Set how many days to keep log data (default: 30 days).
127+
- **Manual cleanup**: Admin interface to trigger immediate cleanup of old logs.
128+
- **Data sanitization**: Remove sensitive fields from logged data for privacy compliance.
129+
122130
- **Simple developer API**
123131
- `Plugin::on()` to subscribe, `Plugin::emit()` to publish, `Plugin::transform()` to modify payloads.
124132

@@ -127,6 +135,126 @@ wpgraphql-logging/
127135

128136
---
129137

138+
## Data Sanitization
139+
140+
WPGraphQL Logging includes robust data sanitization capabilities to help you protect sensitive information while maintaining useful logs for debugging and monitoring. The sanitization system allows you to automatically clean, anonymize, or remove sensitive fields from log records before they are stored.
141+
142+
### Why Data Sanitization Matters
143+
144+
When logging GraphQL requests, context data often contains sensitive information such as:
145+
- User authentication tokens
146+
- Personal identification information (PII)
147+
- Password fields
148+
- Session data
149+
- Internal system information
150+
151+
Data sanitization ensures compliance with privacy regulations (GDPR, CCPA) and security best practices while preserving the debugging value of your logs.
152+
153+
### Sanitization Methods
154+
155+
The plugin offers two sanitization approaches:
156+
157+
#### 1. Recommended Rules (Default)
158+
Pre-configured rules that automatically sanitize common WordPress and WPGraphQL sensitive fields:
159+
- `request.app_context.viewer.data` - User data object
160+
- `request.app_context.viewer.allcaps` - User capabilities
161+
- `request.app_context.viewer.cap_key` - Capability keys
162+
- `request.app_context.viewer.caps` - User capability array
163+
164+
#### 2. Custom Rules
165+
Define your own sanitization rules using dot notation to target specific fields:
166+
167+
**Field Path Examples:**
168+
```
169+
variables.password
170+
request.headers.authorization
171+
user.email
172+
variables.input.creditCard
173+
```
174+
175+
### Sanitization Actions
176+
177+
For each field, you can choose from three sanitization actions:
178+
179+
| Action | Description | Example |
180+
|--------|-------------|---------|
181+
| **Remove** | Completely removes the field from logs | `password: "secret123"`*field removed* |
182+
| **Anonymize** | Replaces value with `***` | `email: "[email protected]"``email: "***"` |
183+
| **Truncate** | Limits string length to 47 characters + `...` | `longText: "Very long text..."``longText: "Very long text that gets cut off here and mo..."` |
184+
185+
### Configuration
186+
187+
Enable and configure data sanitization through the WordPress admin:
188+
189+
1. Navigate to **GraphQL Logging → Settings**
190+
2. Click the **Data Management** tab
191+
3. Enable **Data Sanitization**
192+
4. Choose your sanitization method:
193+
- **Recommended**: Uses pre-configured rules for common sensitive fields
194+
- **Custom**: Define your own field-specific rules
195+
196+
#### Custom Configuration Fields
197+
198+
When using custom rules, configure the following fields:
199+
200+
- **Fields to Remove**: Comma-separated list of field paths to completely remove
201+
- **Fields to Anonymize**: Comma-separated list of field paths to replace with `***`
202+
- **Fields to Truncate**: Comma-separated list of field paths to limit length
203+
204+
**Example Configuration:**
205+
```
206+
Remove: variables.password, request.headers.authorization
207+
Anonymize: user.email, variables.input.personalInfo
208+
Truncate: query, variables.input.description
209+
```
210+
211+
### Developer Hooks
212+
213+
Customize sanitization behavior using WordPress filters:
214+
215+
```php
216+
// Enable/disable sanitization programmatically
217+
add_filter( 'wpgraphql_logging_data_sanitization_enabled', function( $enabled ) {
218+
return current_user_can( 'manage_options' ) ? false : $enabled;
219+
});
220+
221+
// Modify recommended rules
222+
add_filter( 'wpgraphql_logging_data_sanitization_recommended_rules', function( $rules ) {
223+
$rules['custom.sensitive.field'] = 'remove';
224+
return $rules;
225+
});
226+
227+
// Modify all sanitization rules
228+
add_filter( 'wpgraphql_logging_data_sanitization_rules', function( $rules ) {
229+
// Add additional rules or modify existing ones
230+
$rules['request.custom_header'] = 'anonymize';
231+
return $rules;
232+
});
233+
234+
// Modify the final log record after sanitization
235+
add_filter( 'wpgraphql_logging_data_sanitization_record', function( $record ) {
236+
// Additional processing after sanitization
237+
return $record;
238+
});
239+
```
240+
241+
### Performance Considerations
242+
243+
- Sanitization runs on every log record when enabled
244+
- Complex nested field paths may impact performance on high-traffic sites
245+
- Consider using recommended rules for optimal performance
246+
- Test custom rules thoroughly to ensure they target the intended fields
247+
248+
### Security Best Practices
249+
250+
1. **Review logs regularly** to ensure sanitization is working as expected
251+
2. **Test field paths** in a development environment before applying to production
252+
3. **Use remove over anonymize** for highly sensitive data
253+
4. **Monitor performance impact** when implementing extensive custom rules
254+
5. **Keep rules updated** as your GraphQL schema evolves
255+
256+
---
257+
130258
## Usage
131259

132260
WPGraphQL Logging Plugin is highly configurable and extendable and built with developers in mind to allow them to modify, change or add data, loggers etc to this plugin. Please read the docs below:

plugins/wpgraphql-logging/assets/css/settings/wp-graphql-logging-settings.css

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
settings_page_wpgraphql-logging #poststuff .postbox .inside h2 {
1+
.settings_page_wpgraphql-logging #poststuff .postbox .inside h2 {
22
font-size: 1.3em;
33
font-weight: 600;
44
padding-left: 0;
55
}
66

7-
7+
.form-table td input[type="number"],
88
.form-table td input[type="text"] {
99
width: calc(99% - 24px);
1010
display: inline-block;
1111
}
12+
1213
.form-table td select {
1314
width: calc(99% - 24px);
1415
display: inline-block;
@@ -47,12 +48,11 @@ settings_page_wpgraphql-logging #poststuff .postbox .inside h2 {
4748
.wpgraphql-logging-tooltip .tooltip-text::after {
4849
content: "";
4950
position: absolute;
50-
top: 0;
51+
top: 50%;
5152
left: -10px;
5253
border-width: 6px;
5354
border-style: solid;
5455
border-color: transparent #1d2327 transparent transparent;
55-
top: 50%;
5656
transform: translateY(-50%);
5757
}
5858

@@ -71,16 +71,19 @@ settings_page_wpgraphql-logging #poststuff .postbox .inside h2 {
7171
.wpgraphql-logging-docs ul li:before {
7272
content: url(../../icons/doc.svg);
7373
height: 1em;
74+
width: 0.5em;
7475
margin-left: -29px;
7576
margin-top: -2px;
7677
position: absolute;
77-
width: 0.5em;
7878
}
7979

80-
8180
.wpgraphql-logging-feature-list {
8281
list-style-type: disc;
8382
font-size: 1.1em;
8483
margin-left: 30px;
8584
padding-bottom: 16px;
8685
}
86+
87+
.wpgraphql-logging-custom:not(.block) {
88+
display: none;
89+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
document.addEventListener('DOMContentLoaded', function() {
2+
const sanitizationMethodSelect = document.querySelector("#data_sanitization_method");
3+
if (!sanitizationMethodSelect) {
4+
return;
5+
}
6+
7+
function toggleCustomFields() {
8+
const isCustom = sanitizationMethodSelect.value === 'custom';
9+
const customElements = document.querySelectorAll('.wpgraphql-logging-custom');
10+
11+
customElements.forEach((el) => {
12+
if (isCustom) {
13+
el.classList.add('block');
14+
} else {
15+
el.classList.remove('block');
16+
}
17+
});
18+
}
19+
20+
toggleCustomFields();
21+
sanitizationMethodSelect.addEventListener('change', toggleCustomFields);
22+
});

plugins/wpgraphql-logging/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"johnpbloch/wordpress-core": "^6.8",
4949
"lucatume/wp-browser": "^4.0",
5050
"mockery/mockery": "^1.5",
51+
"php-stubs/wordpress-stubs": "^6.8",
5152
"phpcompatibility/php-compatibility": "dev-develop as 9.99.99",
5253
"phpcompatibility/phpcompatibility-wp": "^2.0",
5354
"phpstan/phpstan-strict-rules": "^2.0",

0 commit comments

Comments
 (0)