Automatically redact sensitive data from Google Drive. Protect PII in Google Docs, Sheets, Slides, and uploaded files with seamless Google Workspace integration.
Complete Google Workspace integration
Process Google Docs, Sheets, and Slides directly without export/import.
Trigger redaction on file uploads, edits, or sharing changes.
Support for both personal Drive and Shared Drives (Team Drives).
Work with Google Workspace DLP rules for comprehensive protection.
Deploy across your entire Google Workspace domain with admin consent.
Redact files during Google Vault exports for legal holds.
Google Drive has become the default file storage for millions of organizations using Google Workspace. Documents, spreadsheets, presentations, and uploaded files accumulate across personal drives and shared drives, inevitably containing sensitive personal information. Employee records in Google Sheets, customer data in shared documents, financial information in presentations—all require protection. Automated redaction ensures this data is secured consistently without disrupting the collaborative workflows that make Google Drive valuable.
Our Google Drive integration connects natively with Google Workspace APIs to monitor, process, and protect files automatically. Google-native formats (Docs, Sheets, Slides) are processed directly without manual export steps. Uploaded files in standard formats (PDF, Office documents, images) are handled seamlessly. Whether you need real-time protection for new uploads, batch processing of existing files, or integration with legal hold exports, the integration adapts to your workflow.
The integration leverages Google's standard APIs:
Core Components:
// Integration flow
1. File created/modified in Google Drive
2. Push notification triggers Cloud Function
3. Function retrieves file via Drive API
4. Google Docs converted to processable format
5. Content sent to RedactionAPI
6. Redacted content updated in Drive
7. Audit log entry created
Step 1: Google Cloud Project Setup
// Enable required APIs in Google Cloud Console
- Google Drive API
- Google Docs API
- Google Sheets API
- Google Slides API
- Admin SDK (for domain-wide deployment)
// Create OAuth 2.0 credentials
// or Service Account for server-to-server
Step 2: Configure OAuth Scopes
// Required OAuth scopes
const SCOPES = [
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/documents',
'https://www.googleapis.com/auth/spreadsheets',
'https://www.googleapis.com/auth/presentations'
];
// For domain-wide delegation (admin)
'https://www.googleapis.com/auth/admin.directory.user.readonly'
Step 3: Set Up Push Notifications
// Create Drive watch channel
const channel = await drive.files.watch({
fileId: folderId, // or 'root' for entire drive
requestBody: {
id: uuid(),
type: 'web_hook',
address: 'https://your-function.cloudfunctions.net/driveWebhook',
expiration: Date.now() + 86400000 // 24 hours
}
});
// Renew before expiration
// Channels expire and must be renewed periodically
Step 4: Deploy Cloud Function
// Cloud Function for webhook handling
exports.driveWebhook = async (req, res) => {
// Verify webhook authenticity
const channelId = req.headers['x-goog-channel-id'];
const resourceState = req.headers['x-goog-resource-state'];
if (resourceState === 'sync') {
// Initial sync notification - acknowledge
return res.status(200).send();
}
// Get changed file details
const resourceId = req.headers['x-goog-resource-id'];
const file = await drive.files.get({
fileId: resourceId,
fields: 'id,name,mimeType,modifiedTime'
});
// Process based on file type
let content;
if (file.mimeType === 'application/vnd.google-apps.document') {
// Export Google Doc
content = await drive.files.export({
fileId: resourceId,
mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
});
} else {
// Download binary file
content = await drive.files.get({
fileId: resourceId,
alt: 'media'
});
}
// Send to RedactionAPI
const redacted = await redactionClient.redactFile(content, {
filename: file.name
});
// Update file in Drive
await updateDriveFile(resourceId, redacted, file.mimeType);
res.status(200).send();
};
Google Docs Processing:
async function processGoogleDoc(fileId) {
// Export as DOCX for processing
const exported = await drive.files.export({
fileId: fileId,
mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
});
// Redact
const redacted = await redactionClient.redact({
file: exported,
preserveFormatting: true
});
// Option 1: Update the Google Doc content
// (Converts DOCX back to Google Doc format)
await drive.files.update({
fileId: fileId,
media: {
mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
body: redacted
}
});
// Option 2: Create a new redacted copy
await drive.files.create({
requestBody: {
name: 'Document (Redacted)',
parents: [parentFolderId]
},
media: {
mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
body: redacted
}
});
}
Google Sheets Processing:
async function processGoogleSheet(fileId) {
// Option 1: Export entire sheet as XLSX
const exported = await drive.files.export({
fileId: fileId,
mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
});
// Option 2: Use Sheets API for cell-level access
const sheets = await sheetsApi.spreadsheets.values.get({
spreadsheetId: fileId,
range: 'Sheet1!A1:Z1000'
});
// Redact cell values
const redactedValues = await redactionClient.redactStructured({
data: sheets.data.values,
format: 'grid'
});
// Update sheet with redacted values
await sheetsApi.spreadsheets.values.update({
spreadsheetId: fileId,
range: 'Sheet1!A1:Z1000',
valueInputOption: 'RAW',
requestBody: {
values: redactedValues
}
});
}
Google Slides Processing:
async function processGoogleSlides(fileId) {
// Export as PPTX
const exported = await drive.files.export({
fileId: fileId,
mimeType: 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
});
// Redact
const redacted = await redactionClient.redact({
file: exported,
processImages: true, // OCR and redact text in images
preserveLayout: true
});
// Update presentation
await drive.files.update({
fileId: fileId,
media: {
mimeType: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
body: redacted
}
});
}
Watch Specific Folders:
// Configure folder-specific monitoring
const folderConfig = {
"monitored_folders": [
{
"folderId": "1ABC...",
"name": "HR Documents",
"policies": {
"redactionTypes": ["pii", "ssn", "dob"],
"processSubfolders": true,
"excludePatterns": ["*_redacted*", "templates/*"]
}
},
{
"folderId": "2DEF...",
"name": "Customer Files",
"policies": {
"redactionTypes": ["pii", "financial"],
"triggerOnShare": true
}
}
]
};
Shared Drive Configuration:
// Configure for Shared Drives (Team Drives)
const sharedDriveConfig = {
"driveId": "0APQ...",
"driveName": "Legal Team Drive",
"policies": {
"monitorAllFolders": true,
"redactionTypes": ["all_pii"],
"onExternalShare": "block_and_redact",
"preserveOriginals": true,
"originalLocation": "Archive folder"
}
};
For Google Workspace administrators:
Domain-Wide Delegation:
// Admin console setup
1. Go to Admin Console > Security > API Controls
2. Manage Domain Wide Delegation
3. Add service account client ID
4. Authorize required OAuth scopes
// Service account impersonation
const auth = new google.auth.JWT({
email: serviceAccountEmail,
key: privateKey,
scopes: SCOPES,
subject: '[email protected]' // Impersonate user
});
// Process files as the user
const drive = google.drive({ version: 'v3', auth });
Organization-Wide Policies:
{
"domainPolicies": {
"applyToAllUsers": true,
"exemptGroups": ["[email protected]"],
"defaultRedactionTypes": ["pii"],
"enforceOnExternalShare": true,
"auditToCloudLogging": true,
"dlpIntegration": {
"enabled": true,
"triggerOnDlpAlert": true
}
}
}
Work alongside Google Workspace DLP:
DLP-Triggered Redaction:
// When Google DLP detects sensitive content
// Cloud Function receives DLP alert via Pub/Sub
exports.dlpAlertHandler = async (message, context) => {
const alert = JSON.parse(Buffer.from(message.data, 'base64'));
if (alert.type === 'DLP_CONTENT_MATCHES') {
const fileId = alert.resourceId;
const detectedTypes = alert.detectedInfoTypes;
// Map Google DLP types to our redaction types
const redactionTypes = mapDlpToRedaction(detectedTypes);
// Process the flagged file
await redactDriveFile(fileId, {
types: redactionTypes,
reason: 'dlp_alert',
alertId: alert.id
});
// Update DLP alert status
await updateAlertStatus(alert.id, 'remediated');
}
};
Support for legal and compliance workflows:
Vault Export Processing:
// Process Google Vault export for legal production
async function processVaultExport(exportId, matterId) {
// Download Vault export
const exportFiles = await vault.matters.exports.get({
matterId: matterId,
exportId: exportId
});
// Extract and process each file
for (const file of exportFiles.files) {
// Redact PII while preserving relevant content
const redacted = await redactionClient.redact({
file: file.content,
config: {
preservePatterns: ['case-relevant-terms'],
markRedactions: true,
includeManifest: true
}
});
// Save to production folder
await saveToProduction(redacted, file.metadata);
}
// Generate production report
await generateProductionReport(exportId);
}
Process existing Drive contents:
// Batch process a Drive folder
async function batchProcessFolder(folderId, options) {
let pageToken = null;
const processed = [];
do {
// List files with pagination
const response = await drive.files.list({
q: `'${folderId}' in parents and trashed = false`,
pageSize: 100,
pageToken: pageToken,
fields: 'nextPageToken, files(id, name, mimeType, modifiedTime)'
});
// Process files respecting rate limits
for (const file of response.data.files) {
try {
await processFile(file.id, file.mimeType, options);
processed.push({ id: file.id, status: 'success' });
// Rate limiting
await sleep(options.delayMs || 100);
} catch (error) {
processed.push({ id: file.id, status: 'error', error: error.message });
}
}
pageToken = response.data.nextPageToken;
} while (pageToken);
return processed;
}
Redact when files are shared externally:
// Monitor sharing changes
exports.sharingWebhook = async (req, res) => {
const changes = await getRecentChanges(req.headers);
for (const change of changes) {
// Check if file was shared externally
const permissions = await drive.permissions.list({
fileId: change.fileId
});
const hasExternalShare = permissions.data.permissions.some(
p => p.type === 'anyone' ||
(p.type === 'user' && !p.emailAddress.endsWith('@company.com'))
);
if (hasExternalShare && !isAlreadyRedacted(change.fileId)) {
// Redact before external access
await redactDriveFile(change.fileId);
// Notify file owner
await notifyOwner(change.fileId, 'File redacted before external sharing');
}
}
res.status(200).send();
};
// Audit log entry to Cloud Logging
const logEntry = {
severity: 'INFO',
jsonPayload: {
event: 'file_redacted',
fileId: fileId,
fileName: fileName,
driveType: 'shared_drive',
driveId: driveId,
triggerType: 'file_upload',
detections: {
pii: 15,
ssn: 2,
email: 8
},
processingTime: 1250,
user: userEmail
},
resource: {
type: 'cloud_function',
labels: {
function_name: 'driveRedaction'
}
}
};
await logging.write(logging.entry(logEntry));
The integration uses Google Drive API and Push Notifications to detect file changes. When files are created or modified, they're automatically processed for redaction. Google native formats (Docs, Sheets, Slides) are converted, redacted, and converted back preserving formatting.
Yes, we process Google Docs, Sheets, and Slides in their native format. The API exports to a processable format, redacts PII, and updates the original document. Comments, suggestions, and revision history can optionally be cleared.
Yes, the integration supports both personal My Drive and Shared Drives (formerly Team Drives). For Shared Drives, you can configure which drives to monitor and set drive-specific redaction policies.
With Google Workspace admin consent, the integration can monitor files across your entire domain. Domain-wide delegation enables service account access to user files according to your configured policies.
Yes, Google Workspace DLP can trigger our redaction when sensitive content is detected. Alternatively, our redaction can supplement DLP by actually removing PII rather than just alerting. Both approaches work together.
For legal and compliance, we can process Google Vault exports. Files under legal hold are redacted during export, creating production-ready versions while preserving originals under hold.