@cloudstreamsoftware/claude-tools 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +152 -37
- package/agents/INDEX.md +183 -0
- package/agents/architect.md +247 -0
- package/agents/build-error-resolver.md +555 -0
- package/agents/catalyst-deployer.md +132 -0
- package/agents/code-reviewer.md +121 -0
- package/agents/compliance-auditor.md +148 -0
- package/agents/creator-architect.md +395 -0
- package/agents/deluge-reviewer.md +98 -0
- package/agents/doc-updater.md +471 -0
- package/agents/e2e-runner.md +711 -0
- package/agents/planner.md +122 -0
- package/agents/refactor-cleaner.md +309 -0
- package/agents/security-reviewer.md +582 -0
- package/agents/tdd-guide.md +302 -0
- package/bin/cloudstream-setup.js +16 -6
- package/config/versions.json +63 -0
- package/dist/hooks/hooks.json +209 -0
- package/dist/index.js +47 -0
- package/dist/lib/asset-value.js +609 -0
- package/dist/lib/client-manager.js +300 -0
- package/dist/lib/command-matcher.js +242 -0
- package/dist/lib/cross-session-patterns.js +754 -0
- package/dist/lib/intent-classifier.js +1075 -0
- package/dist/lib/package-manager.js +374 -0
- package/dist/lib/recommendation-engine.js +597 -0
- package/dist/lib/session-memory.js +489 -0
- package/dist/lib/skill-effectiveness.js +486 -0
- package/dist/lib/skill-matcher.js +595 -0
- package/dist/lib/tutorial-metrics.js +242 -0
- package/dist/lib/tutorial-progress.js +209 -0
- package/dist/lib/tutorial-renderer.js +431 -0
- package/dist/lib/utils.js +380 -0
- package/dist/lib/verify-formatter.js +143 -0
- package/dist/lib/workflow-state.js +249 -0
- package/hooks/hooks.json +209 -0
- package/package.json +5 -1
- package/scripts/aggregate-sessions.js +290 -0
- package/scripts/branch-name-validator.js +291 -0
- package/scripts/build.js +101 -0
- package/scripts/commands/client-switch.js +231 -0
- package/scripts/deprecate-skill.js +610 -0
- package/scripts/diagnose.js +324 -0
- package/scripts/doc-freshness.js +168 -0
- package/scripts/generate-weekly-digest.js +393 -0
- package/scripts/health-check.js +270 -0
- package/scripts/hooks/credential-check.js +101 -0
- package/scripts/hooks/evaluate-session.js +81 -0
- package/scripts/hooks/pre-compact.js +66 -0
- package/scripts/hooks/prompt-analyzer.js +276 -0
- package/scripts/hooks/prompt-router.js +422 -0
- package/scripts/hooks/quality-gate-enforcer.js +371 -0
- package/scripts/hooks/session-end.js +156 -0
- package/scripts/hooks/session-start.js +195 -0
- package/scripts/hooks/skill-injector.js +333 -0
- package/scripts/hooks/suggest-compact.js +58 -0
- package/scripts/lib/asset-value.js +609 -0
- package/scripts/lib/client-manager.js +300 -0
- package/scripts/lib/command-matcher.js +242 -0
- package/scripts/lib/cross-session-patterns.js +754 -0
- package/scripts/lib/intent-classifier.js +1075 -0
- package/scripts/lib/package-manager.js +374 -0
- package/scripts/lib/recommendation-engine.js +597 -0
- package/scripts/lib/session-memory.js +489 -0
- package/scripts/lib/skill-effectiveness.js +486 -0
- package/scripts/lib/skill-matcher.js +595 -0
- package/scripts/lib/tutorial-metrics.js +242 -0
- package/scripts/lib/tutorial-progress.js +209 -0
- package/scripts/lib/tutorial-renderer.js +431 -0
- package/scripts/lib/utils.js +380 -0
- package/scripts/lib/verify-formatter.js +143 -0
- package/scripts/lib/workflow-state.js +249 -0
- package/scripts/onboard.js +363 -0
- package/scripts/quarterly-report.js +692 -0
- package/scripts/setup-package-manager.js +204 -0
- package/scripts/sync-upstream.js +391 -0
- package/scripts/test.js +108 -0
- package/scripts/tutorial-runner.js +351 -0
- package/scripts/validate-all.js +201 -0
- package/scripts/verifiers/agents.js +245 -0
- package/scripts/verifiers/config.js +186 -0
- package/scripts/verifiers/environment.js +123 -0
- package/scripts/verifiers/hooks.js +188 -0
- package/scripts/verifiers/index.js +38 -0
- package/scripts/verifiers/persistence.js +140 -0
- package/scripts/verifiers/plugin.js +215 -0
- package/scripts/verifiers/skills.js +209 -0
- package/scripts/verify-setup.js +164 -0
- package/skills/INDEX.md +157 -0
- package/skills/backend-patterns/SKILL.md +586 -0
- package/skills/backend-patterns/catalyst-patterns.md +128 -0
- package/skills/bigquery-patterns/SKILL.md +27 -0
- package/skills/bigquery-patterns/performance-optimization.md +518 -0
- package/skills/bigquery-patterns/query-patterns.md +372 -0
- package/skills/bigquery-patterns/schema-design.md +78 -0
- package/skills/cloudstream-project-template/SKILL.md +20 -0
- package/skills/cloudstream-project-template/structure.md +65 -0
- package/skills/coding-standards/SKILL.md +524 -0
- package/skills/coding-standards/deluge-standards.md +83 -0
- package/skills/compliance-patterns/SKILL.md +28 -0
- package/skills/compliance-patterns/hipaa/audit-requirements.md +251 -0
- package/skills/compliance-patterns/hipaa/baa-process.md +298 -0
- package/skills/compliance-patterns/hipaa/data-archival-strategy.md +387 -0
- package/skills/compliance-patterns/hipaa/phi-handling.md +52 -0
- package/skills/compliance-patterns/pci-dss/saq-a-requirements.md +307 -0
- package/skills/compliance-patterns/pci-dss/tokenization-patterns.md +382 -0
- package/skills/compliance-patterns/pci-dss/zoho-checkout-patterns.md +56 -0
- package/skills/compliance-patterns/soc2/access-controls.md +344 -0
- package/skills/compliance-patterns/soc2/audit-logging.md +458 -0
- package/skills/compliance-patterns/soc2/change-management.md +403 -0
- package/skills/compliance-patterns/soc2/deluge-execution-logging.md +407 -0
- package/skills/consultancy-workflows/SKILL.md +19 -0
- package/skills/consultancy-workflows/client-isolation.md +21 -0
- package/skills/consultancy-workflows/documentation-automation.md +454 -0
- package/skills/consultancy-workflows/handoff-procedures.md +257 -0
- package/skills/consultancy-workflows/knowledge-capture.md +513 -0
- package/skills/consultancy-workflows/time-tracking.md +26 -0
- package/skills/continuous-learning/SKILL.md +84 -0
- package/skills/continuous-learning/config.json +18 -0
- package/skills/continuous-learning/evaluate-session.sh +60 -0
- package/skills/continuous-learning-v2/SKILL.md +126 -0
- package/skills/continuous-learning-v2/config.json +61 -0
- package/skills/frontend-patterns/SKILL.md +635 -0
- package/skills/frontend-patterns/zoho-widget-patterns.md +103 -0
- package/skills/gcp-data-engineering/SKILL.md +36 -0
- package/skills/gcp-data-engineering/bigquery/performance-optimization.md +337 -0
- package/skills/gcp-data-engineering/dataflow/error-handling.md +496 -0
- package/skills/gcp-data-engineering/dataflow/pipeline-patterns.md +444 -0
- package/skills/gcp-data-engineering/dbt/model-organization.md +63 -0
- package/skills/gcp-data-engineering/dbt/testing-patterns.md +503 -0
- package/skills/gcp-data-engineering/medallion-architecture/bronze-layer.md +60 -0
- package/skills/gcp-data-engineering/medallion-architecture/gold-layer.md +311 -0
- package/skills/gcp-data-engineering/medallion-architecture/layer-transitions.md +517 -0
- package/skills/gcp-data-engineering/medallion-architecture/silver-layer.md +305 -0
- package/skills/gcp-data-engineering/zoho-to-gcp/data-extraction.md +543 -0
- package/skills/gcp-data-engineering/zoho-to-gcp/real-time-vs-batch.md +337 -0
- package/skills/security-review/SKILL.md +498 -0
- package/skills/security-review/compliance-checklist.md +53 -0
- package/skills/strategic-compact/SKILL.md +67 -0
- package/skills/tdd-workflow/SKILL.md +413 -0
- package/skills/tdd-workflow/zoho-testing.md +124 -0
- package/skills/tutorial/SKILL.md +249 -0
- package/skills/tutorial/docs/ACCESSIBILITY.md +169 -0
- package/skills/tutorial/lessons/00-philosophy-and-workflow.md +198 -0
- package/skills/tutorial/lessons/01-basics.md +81 -0
- package/skills/tutorial/lessons/02-training.md +86 -0
- package/skills/tutorial/lessons/03-commands.md +109 -0
- package/skills/tutorial/lessons/04-workflows.md +115 -0
- package/skills/tutorial/lessons/05-compliance.md +116 -0
- package/skills/tutorial/lessons/06-zoho.md +121 -0
- package/skills/tutorial/lessons/07-hooks-system.md +277 -0
- package/skills/tutorial/lessons/08-mcp-servers.md +316 -0
- package/skills/tutorial/lessons/09-client-management.md +215 -0
- package/skills/tutorial/lessons/10-testing-e2e.md +260 -0
- package/skills/tutorial/lessons/11-skills-deep-dive.md +272 -0
- package/skills/tutorial/lessons/12-rules-system.md +326 -0
- package/skills/tutorial/lessons/13-golden-standard-graduation.md +213 -0
- package/skills/tutorial/lessons/14-fork-setup-and-sync.md +312 -0
- package/skills/tutorial/lessons/15-living-examples-system.md +221 -0
- package/skills/tutorial/tracks/accelerated/README.md +134 -0
- package/skills/tutorial/tracks/accelerated/assessment/checkpoint-1.md +161 -0
- package/skills/tutorial/tracks/accelerated/assessment/checkpoint-2.md +175 -0
- package/skills/tutorial/tracks/accelerated/day-1-core-concepts.md +234 -0
- package/skills/tutorial/tracks/accelerated/day-2-essential-commands.md +270 -0
- package/skills/tutorial/tracks/accelerated/day-3-workflow-mastery.md +305 -0
- package/skills/tutorial/tracks/accelerated/day-4-compliance-zoho.md +304 -0
- package/skills/tutorial/tracks/accelerated/day-5-hooks-skills.md +344 -0
- package/skills/tutorial/tracks/accelerated/day-6-client-testing.md +386 -0
- package/skills/tutorial/tracks/accelerated/day-7-graduation.md +369 -0
- package/skills/zoho-patterns/CHANGELOG.md +108 -0
- package/skills/zoho-patterns/SKILL.md +446 -0
- package/skills/zoho-patterns/analytics/dashboard-patterns.md +352 -0
- package/skills/zoho-patterns/analytics/zoho-to-bigquery-pipeline.md +427 -0
- package/skills/zoho-patterns/catalyst/appsail-deployment.md +349 -0
- package/skills/zoho-patterns/catalyst/context-close-patterns.md +354 -0
- package/skills/zoho-patterns/catalyst/cron-batch-processing.md +374 -0
- package/skills/zoho-patterns/catalyst/function-patterns.md +439 -0
- package/skills/zoho-patterns/creator/form-design.md +304 -0
- package/skills/zoho-patterns/creator/publish-api-patterns.md +313 -0
- package/skills/zoho-patterns/creator/widget-integration.md +306 -0
- package/skills/zoho-patterns/creator/workflow-automation.md +253 -0
- package/skills/zoho-patterns/deluge/api-patterns.md +468 -0
- package/skills/zoho-patterns/deluge/batch-processing.md +403 -0
- package/skills/zoho-patterns/deluge/cross-app-integration.md +356 -0
- package/skills/zoho-patterns/deluge/error-handling.md +423 -0
- package/skills/zoho-patterns/deluge/syntax-reference.md +65 -0
- package/skills/zoho-patterns/integration/cors-proxy-architecture.md +426 -0
- package/skills/zoho-patterns/integration/crm-books-native-sync.md +277 -0
- package/skills/zoho-patterns/integration/oauth-token-management.md +461 -0
- package/skills/zoho-patterns/integration/zoho-flow-patterns.md +334 -0
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
# SOC2 Audit Logging for Zoho
|
|
2
|
+
|
|
3
|
+
## Why Custom Logging is Required
|
|
4
|
+
|
|
5
|
+
Zoho Creator does NOT automatically log:
|
|
6
|
+
- Deluge script executions
|
|
7
|
+
- API calls made via `invokeUrl`
|
|
8
|
+
- Record reads (only modifications are logged natively)
|
|
9
|
+
- Export/download events
|
|
10
|
+
- Failed access attempts
|
|
11
|
+
|
|
12
|
+
For SOC2 Trust Service Criteria (specifically CC7.2 and CC7.3), you MUST implement custom audit logging for all sensitive operations.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## SOC2 Trust Service Criteria Mapping
|
|
17
|
+
|
|
18
|
+
| Criteria | Requirement | Implementation |
|
|
19
|
+
|----------|-------------|----------------|
|
|
20
|
+
| CC6.1 | Logical access controls | Role-based field permissions |
|
|
21
|
+
| CC6.2 | User authentication | Zoho login + MFA |
|
|
22
|
+
| CC6.3 | Access management | Quarterly access reviews |
|
|
23
|
+
| CC7.1 | Change management | Change_Request form + approval workflow |
|
|
24
|
+
| CC7.2 | System monitoring | Custom audit logging (this document) |
|
|
25
|
+
| CC7.3 | Anomaly detection | Scheduled queries on audit data |
|
|
26
|
+
| CC8.1 | Incident response | Incident form + escalation workflow |
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Audit Log Form Structure
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
Form: SOC2_Audit_Log
|
|
34
|
+
Fields:
|
|
35
|
+
- Log_ID (Auto-number, primary key)
|
|
36
|
+
- Timestamp (DateTime, auto-filled: zoho.currenttime)
|
|
37
|
+
- User_ID (Single Line, auto-filled: zoho.loginuserid)
|
|
38
|
+
- User_Email (Email, auto-filled: zoho.loginuser)
|
|
39
|
+
- User_Role (Single Line, auto-filled: zoho.loginuserRole)
|
|
40
|
+
- Action_Type (Picklist: CREATE/READ/UPDATE/DELETE/EXPORT/LOGIN/LOGOUT/DENIED/ADMIN)
|
|
41
|
+
- Target_Form (Single Line)
|
|
42
|
+
- Target_Record_ID (Single Line)
|
|
43
|
+
- Field_Name (Single Line, nullable - for field-level changes)
|
|
44
|
+
- Old_Value (Multi Line, nullable - before state)
|
|
45
|
+
- New_Value (Multi Line, nullable - after state)
|
|
46
|
+
- IP_Address (Single Line, auto-filled: zoho.ipaddress)
|
|
47
|
+
- Result (Picklist: SUCCESS/FAILURE/DENIED)
|
|
48
|
+
- Risk_Level (Picklist: LOW/MEDIUM/HIGH/CRITICAL)
|
|
49
|
+
- Session_ID (Single Line, nullable)
|
|
50
|
+
- Notes (Multi Line, nullable)
|
|
51
|
+
|
|
52
|
+
Permissions:
|
|
53
|
+
- Create: All roles (via Deluge only, not direct form access)
|
|
54
|
+
- Edit: None (logs are immutable)
|
|
55
|
+
- Delete: None (logs are immutable)
|
|
56
|
+
- View: Admin, Compliance, Auditor roles only
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Core Logging Function
|
|
62
|
+
|
|
63
|
+
```deluge
|
|
64
|
+
// ============================================================
|
|
65
|
+
// FUNCTION: logAuditEvent
|
|
66
|
+
// PURPOSE: Create an immutable audit log entry for SOC2 compliance
|
|
67
|
+
// USAGE: Call in EVERY workflow that reads, modifies, or deletes data
|
|
68
|
+
// ============================================================
|
|
69
|
+
|
|
70
|
+
void logAuditEvent(String actionType, String targetForm, String recordId, Map changes, String riskLevel)
|
|
71
|
+
{
|
|
72
|
+
logMap = Map();
|
|
73
|
+
logMap.put("Timestamp", zoho.currenttime);
|
|
74
|
+
logMap.put("User_ID", zoho.loginuserid);
|
|
75
|
+
logMap.put("User_Email", zoho.loginuser);
|
|
76
|
+
logMap.put("User_Role", ifnull(zoho.loginuserRole, "system"));
|
|
77
|
+
logMap.put("Action_Type", actionType);
|
|
78
|
+
logMap.put("Target_Form", targetForm);
|
|
79
|
+
logMap.put("Target_Record_ID", recordId);
|
|
80
|
+
logMap.put("IP_Address", ifnull(zoho.ipaddress, "internal"));
|
|
81
|
+
logMap.put("Result", "SUCCESS");
|
|
82
|
+
logMap.put("Risk_Level", riskLevel);
|
|
83
|
+
|
|
84
|
+
// Store field-level changes
|
|
85
|
+
if (changes != null && changes.size() > 0)
|
|
86
|
+
{
|
|
87
|
+
if (changes.containsKey("field"))
|
|
88
|
+
{
|
|
89
|
+
logMap.put("Field_Name", changes.get("field"));
|
|
90
|
+
}
|
|
91
|
+
if (changes.containsKey("old"))
|
|
92
|
+
{
|
|
93
|
+
logMap.put("Old_Value", changes.get("old"));
|
|
94
|
+
}
|
|
95
|
+
if (changes.containsKey("new"))
|
|
96
|
+
{
|
|
97
|
+
logMap.put("New_Value", changes.get("new"));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
zoho.creator.createRecord("app", "SOC2_Audit_Log", logMap);
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Usage in Workflows
|
|
106
|
+
|
|
107
|
+
```deluge
|
|
108
|
+
// On Record Create
|
|
109
|
+
logAuditEvent("CREATE", "Customers", input.ID.toString(), null, "LOW");
|
|
110
|
+
|
|
111
|
+
// On Record Update (with before/after)
|
|
112
|
+
changes = Map();
|
|
113
|
+
changes.put("field", "Status");
|
|
114
|
+
changes.put("old", input.previous.Status);
|
|
115
|
+
changes.put("new", input.Status);
|
|
116
|
+
logAuditEvent("UPDATE", "Customers", input.ID.toString(), changes, "MEDIUM");
|
|
117
|
+
|
|
118
|
+
// On Record Delete
|
|
119
|
+
logAuditEvent("DELETE", "Invoices", input.ID.toString(), null, "HIGH");
|
|
120
|
+
|
|
121
|
+
// On Failed Access Attempt
|
|
122
|
+
failMap = Map();
|
|
123
|
+
failMap.put("Timestamp", zoho.currenttime);
|
|
124
|
+
failMap.put("User_Email", zoho.loginuser);
|
|
125
|
+
failMap.put("Action_Type", "DENIED");
|
|
126
|
+
failMap.put("Target_Form", "Financial_Records");
|
|
127
|
+
failMap.put("Result", "DENIED");
|
|
128
|
+
failMap.put("Risk_Level", "CRITICAL");
|
|
129
|
+
failMap.put("Notes", "Insufficient role for financial data access");
|
|
130
|
+
zoho.creator.createRecord("app", "SOC2_Audit_Log", failMap);
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## BigQuery Export for Long-Term Retention
|
|
136
|
+
|
|
137
|
+
SOC2 requires audit logs to be retained for the engagement period (typically 12 months minimum, often longer per client contract). Export to BigQuery for cost-effective long-term storage.
|
|
138
|
+
|
|
139
|
+
### BigQuery Audit Table
|
|
140
|
+
|
|
141
|
+
```sql
|
|
142
|
+
CREATE TABLE `project.compliance.soc2_audit_logs` (
|
|
143
|
+
log_id STRING NOT NULL,
|
|
144
|
+
timestamp TIMESTAMP NOT NULL,
|
|
145
|
+
user_id STRING,
|
|
146
|
+
user_email STRING NOT NULL,
|
|
147
|
+
user_role STRING,
|
|
148
|
+
action_type STRING NOT NULL,
|
|
149
|
+
target_form STRING NOT NULL,
|
|
150
|
+
target_record_id STRING,
|
|
151
|
+
field_name STRING,
|
|
152
|
+
old_value STRING,
|
|
153
|
+
new_value STRING,
|
|
154
|
+
ip_address STRING,
|
|
155
|
+
result STRING NOT NULL,
|
|
156
|
+
risk_level STRING,
|
|
157
|
+
session_id STRING,
|
|
158
|
+
notes STRING,
|
|
159
|
+
client_id STRING NOT NULL,
|
|
160
|
+
source_org STRING NOT NULL,
|
|
161
|
+
archive_date TIMESTAMP NOT NULL,
|
|
162
|
+
archive_batch_id STRING NOT NULL
|
|
163
|
+
)
|
|
164
|
+
PARTITION BY DATE(timestamp)
|
|
165
|
+
CLUSTER BY client_id, action_type, user_email;
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Automated Monthly Export (Catalyst Cron)
|
|
169
|
+
|
|
170
|
+
```javascript
|
|
171
|
+
'use strict';
|
|
172
|
+
|
|
173
|
+
const catalyst = require('zcatalyst-sdk-node');
|
|
174
|
+
const { BigQuery } = require('@google-cloud/bigquery');
|
|
175
|
+
|
|
176
|
+
module.exports = async (cronDetails, context) => {
|
|
177
|
+
const app = catalyst.initialize(context);
|
|
178
|
+
const bigquery = new BigQuery();
|
|
179
|
+
const batchId = `soc2-${Date.now()}`;
|
|
180
|
+
let exportedCount = 0;
|
|
181
|
+
|
|
182
|
+
try {
|
|
183
|
+
// Calculate date range: previous month
|
|
184
|
+
const now = new Date();
|
|
185
|
+
const startDate = new Date(now.getFullYear(), now.getMonth() - 1, 1);
|
|
186
|
+
const endDate = new Date(now.getFullYear(), now.getMonth(), 0);
|
|
187
|
+
|
|
188
|
+
console.log(`Exporting SOC2 logs: ${startDate.toISOString()} to ${endDate.toISOString()}`);
|
|
189
|
+
|
|
190
|
+
// Fetch logs from Creator (paginated)
|
|
191
|
+
const allLogs = [];
|
|
192
|
+
let page = 1;
|
|
193
|
+
let hasMore = true;
|
|
194
|
+
|
|
195
|
+
while (hasMore) {
|
|
196
|
+
const criteria = `Timestamp >= "${startDate.toISOString()}" && Timestamp <= "${endDate.toISOString()}"`;
|
|
197
|
+
const response = await fetchCreatorRecords(app, 'SOC2_Audit_Log', criteria, page);
|
|
198
|
+
|
|
199
|
+
if (response.length > 0) {
|
|
200
|
+
allLogs.push(...response);
|
|
201
|
+
page++;
|
|
202
|
+
} else {
|
|
203
|
+
hasMore = false;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (page > 100) {
|
|
207
|
+
console.log('Safety limit reached at page 100');
|
|
208
|
+
hasMore = false;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (allLogs.length === 0) {
|
|
213
|
+
console.log('No logs to export for this period');
|
|
214
|
+
context.close();
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Transform for BigQuery
|
|
219
|
+
const rows = allLogs.map(log => ({
|
|
220
|
+
log_id: String(log.Log_ID),
|
|
221
|
+
timestamp: log.Timestamp,
|
|
222
|
+
user_id: log.User_ID,
|
|
223
|
+
user_email: log.User_Email,
|
|
224
|
+
user_role: log.User_Role,
|
|
225
|
+
action_type: log.Action_Type,
|
|
226
|
+
target_form: log.Target_Form,
|
|
227
|
+
target_record_id: log.Target_Record_ID,
|
|
228
|
+
field_name: log.Field_Name || null,
|
|
229
|
+
old_value: log.Old_Value || null,
|
|
230
|
+
new_value: log.New_Value || null,
|
|
231
|
+
ip_address: log.IP_Address,
|
|
232
|
+
result: log.Result,
|
|
233
|
+
risk_level: log.Risk_Level || 'LOW',
|
|
234
|
+
session_id: log.Session_ID || null,
|
|
235
|
+
notes: log.Notes || null,
|
|
236
|
+
client_id: process.env.CLIENT_ID,
|
|
237
|
+
source_org: process.env.ZOHO_ORG_ID,
|
|
238
|
+
archive_date: new Date().toISOString(),
|
|
239
|
+
archive_batch_id: batchId
|
|
240
|
+
}));
|
|
241
|
+
|
|
242
|
+
// Insert into BigQuery
|
|
243
|
+
const dataset = bigquery.dataset('compliance');
|
|
244
|
+
const table = dataset.table('soc2_audit_logs');
|
|
245
|
+
await table.insert(rows);
|
|
246
|
+
exportedCount = rows.length;
|
|
247
|
+
|
|
248
|
+
console.log(`Exported ${exportedCount} SOC2 audit logs (batch: ${batchId})`);
|
|
249
|
+
} catch (error) {
|
|
250
|
+
console.error(`SOC2 export error: ${error.message}`);
|
|
251
|
+
// Send alert to compliance team
|
|
252
|
+
} finally {
|
|
253
|
+
context.close(); // MANDATORY
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
async function fetchCreatorRecords(app, formName, criteria, page) {
|
|
258
|
+
// Use Zoho Creator API to fetch records
|
|
259
|
+
// Implementation depends on your OAuth setup
|
|
260
|
+
return [];
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## Log Rotation and Retention
|
|
267
|
+
|
|
268
|
+
| Environment | Retention Period | Storage | Cost |
|
|
269
|
+
|-------------|-----------------|---------|------|
|
|
270
|
+
| Creator (live) | 3 months | Zoho storage | Included in plan |
|
|
271
|
+
| BigQuery (archive) | 3 years minimum | GCS long-term | ~$0.01/GB/month |
|
|
272
|
+
| Cold storage (legal hold) | 7 years | GCS Archive class | ~$0.004/GB/month |
|
|
273
|
+
|
|
274
|
+
### Rotation Schedule
|
|
275
|
+
|
|
276
|
+
- **Monthly**: Export previous month's logs to BigQuery
|
|
277
|
+
- **Quarterly**: Verify export completeness (Creator count vs. BigQuery count)
|
|
278
|
+
- **Annually**: Move logs older than 3 years to cold storage
|
|
279
|
+
- **On demand**: Export on auditor request
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Anomaly Detection Queries
|
|
284
|
+
|
|
285
|
+
### Unusual Access Patterns
|
|
286
|
+
|
|
287
|
+
```sql
|
|
288
|
+
-- Users accessing significantly more records than their average
|
|
289
|
+
WITH user_daily AS (
|
|
290
|
+
SELECT user_email, DATE(timestamp) AS access_date,
|
|
291
|
+
COUNT(*) AS daily_actions
|
|
292
|
+
FROM `project.compliance.soc2_audit_logs`
|
|
293
|
+
WHERE timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 90 DAY)
|
|
294
|
+
GROUP BY user_email, DATE(timestamp)
|
|
295
|
+
),
|
|
296
|
+
user_stats AS (
|
|
297
|
+
SELECT user_email,
|
|
298
|
+
AVG(daily_actions) AS avg_daily,
|
|
299
|
+
STDDEV(daily_actions) AS stddev_daily
|
|
300
|
+
FROM user_daily
|
|
301
|
+
GROUP BY user_email
|
|
302
|
+
)
|
|
303
|
+
SELECT d.user_email, d.access_date, d.daily_actions,
|
|
304
|
+
s.avg_daily, s.stddev_daily
|
|
305
|
+
FROM user_daily d
|
|
306
|
+
JOIN user_stats s ON d.user_email = s.user_email
|
|
307
|
+
WHERE d.daily_actions > s.avg_daily + (3 * s.stddev_daily)
|
|
308
|
+
ORDER BY d.daily_actions DESC;
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### After-Hours Access
|
|
312
|
+
|
|
313
|
+
```sql
|
|
314
|
+
-- Access outside business hours (adjust timezone as needed)
|
|
315
|
+
SELECT user_email, timestamp, action_type, target_form, target_record_id
|
|
316
|
+
FROM `project.compliance.soc2_audit_logs`
|
|
317
|
+
WHERE (EXTRACT(HOUR FROM timestamp) < 7 OR EXTRACT(HOUR FROM timestamp) > 19)
|
|
318
|
+
AND EXTRACT(DAYOFWEEK FROM timestamp) NOT IN (1, 7) -- Not weekends
|
|
319
|
+
AND action_type IN ('READ', 'UPDATE', 'DELETE', 'EXPORT')
|
|
320
|
+
AND timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
|
|
321
|
+
ORDER BY timestamp DESC;
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Failed Access Attempts
|
|
325
|
+
|
|
326
|
+
```sql
|
|
327
|
+
-- Multiple denied attempts (potential unauthorized access)
|
|
328
|
+
SELECT user_email, DATE(timestamp) AS attempt_date,
|
|
329
|
+
COUNT(*) AS denied_count,
|
|
330
|
+
ARRAY_AGG(DISTINCT target_form) AS attempted_forms
|
|
331
|
+
FROM `project.compliance.soc2_audit_logs`
|
|
332
|
+
WHERE result = 'DENIED'
|
|
333
|
+
AND timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
|
|
334
|
+
GROUP BY user_email, DATE(timestamp)
|
|
335
|
+
HAVING denied_count >= 3
|
|
336
|
+
ORDER BY denied_count DESC;
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## Change Management Workflow
|
|
342
|
+
|
|
343
|
+
Since Creator lacks native change management, implement a custom approval flow:
|
|
344
|
+
|
|
345
|
+
### Change Request Form
|
|
346
|
+
|
|
347
|
+
```
|
|
348
|
+
Form: Change_Request
|
|
349
|
+
Fields:
|
|
350
|
+
- Request_ID (Auto-number)
|
|
351
|
+
- Requested_By (Email, auto-filled)
|
|
352
|
+
- Request_Date (DateTime, auto-filled)
|
|
353
|
+
- Change_Type (Picklist: Schema/Workflow/Permission/Integration/Config)
|
|
354
|
+
- Description (Multi Line, required)
|
|
355
|
+
- Justification (Multi Line, required)
|
|
356
|
+
- Risk_Assessment (Picklist: Low/Medium/High/Critical)
|
|
357
|
+
- Affected_Forms (Multi Select)
|
|
358
|
+
- Rollback_Plan (Multi Line, required)
|
|
359
|
+
- Approval_Status (Picklist: Pending/Approved/Rejected/Implemented/Rolled Back)
|
|
360
|
+
- Approved_By (Email, nullable)
|
|
361
|
+
- Approval_Date (DateTime, nullable)
|
|
362
|
+
- Implementation_Date (DateTime, nullable)
|
|
363
|
+
- Implementation_Notes (Multi Line, nullable)
|
|
364
|
+
- Verification_Status (Picklist: Pending/Passed/Failed)
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### Approval Workflow (Blueprint)
|
|
368
|
+
|
|
369
|
+
```
|
|
370
|
+
States: Draft → Pending Review → Approved → Implementing → Verified → Closed
|
|
371
|
+
↘ Rejected
|
|
372
|
+
↘ Rollback Required → Rolled Back → Closed
|
|
373
|
+
|
|
374
|
+
Transitions:
|
|
375
|
+
Draft → Pending Review: Submitter fills all required fields
|
|
376
|
+
Pending Review → Approved: Manager approves (requires different user)
|
|
377
|
+
Pending Review → Rejected: Manager provides rejection reason
|
|
378
|
+
Approved → Implementing: Developer begins implementation
|
|
379
|
+
Implementing → Verified: QA confirms change works correctly
|
|
380
|
+
Implementing → Rollback Required: Issue detected
|
|
381
|
+
Verified → Closed: Auto-log completion in audit trail
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
## Quarterly Access Review Process
|
|
387
|
+
|
|
388
|
+
### Review Checklist
|
|
389
|
+
|
|
390
|
+
- [ ] Export all active user permissions from Creator
|
|
391
|
+
- [ ] Compare against approved access matrix
|
|
392
|
+
- [ ] Identify users with access no longer justified
|
|
393
|
+
- [ ] Revoke unnecessary permissions
|
|
394
|
+
- [ ] Document all changes in Change_Request form
|
|
395
|
+
- [ ] Get manager sign-off on access decisions
|
|
396
|
+
- [ ] Update access matrix document
|
|
397
|
+
- [ ] Log review completion in SOC2_Audit_Log
|
|
398
|
+
|
|
399
|
+
### Access Review Query
|
|
400
|
+
|
|
401
|
+
```sql
|
|
402
|
+
-- All users and their most recent activity
|
|
403
|
+
SELECT user_email, user_role,
|
|
404
|
+
MAX(timestamp) AS last_activity,
|
|
405
|
+
COUNT(*) AS total_actions_90d,
|
|
406
|
+
ARRAY_AGG(DISTINCT action_type) AS action_types,
|
|
407
|
+
ARRAY_AGG(DISTINCT target_form) AS accessed_forms
|
|
408
|
+
FROM `project.compliance.soc2_audit_logs`
|
|
409
|
+
WHERE timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 90 DAY)
|
|
410
|
+
GROUP BY user_email, user_role
|
|
411
|
+
ORDER BY last_activity DESC;
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## Alerting Configuration
|
|
417
|
+
|
|
418
|
+
| Condition | Alert Level | Notify | Response Time |
|
|
419
|
+
|-----------|-------------|--------|---------------|
|
|
420
|
+
| 5+ DENIED events in 1 hour | Critical | Admin + Compliance | Immediate |
|
|
421
|
+
| DELETE on financial form | High | Admin | Within 1 hour |
|
|
422
|
+
| EXPORT of >1000 records | High | Data Owner | Within 4 hours |
|
|
423
|
+
| After-hours ADMIN action | Medium | Admin | Next business day |
|
|
424
|
+
| New user first login | Low | Admin | Acknowledge within 24h |
|
|
425
|
+
|
|
426
|
+
### Alert Implementation (Scheduled Function)
|
|
427
|
+
|
|
428
|
+
```deluge
|
|
429
|
+
// Scheduled function: runs every 15 minutes
|
|
430
|
+
// Check for critical alert conditions
|
|
431
|
+
|
|
432
|
+
oneHourAgo = zoho.currenttime.subHour(1);
|
|
433
|
+
criteria = "Result == \"DENIED\" && Timestamp >= \"" + oneHourAgo + "\"";
|
|
434
|
+
deniedLogs = zoho.creator.getRecords("app", "SOC2_Audit_Log_Report", criteria, 1, 200);
|
|
435
|
+
|
|
436
|
+
// Group by user
|
|
437
|
+
userDenials = Map();
|
|
438
|
+
for each log in deniedLogs
|
|
439
|
+
{
|
|
440
|
+
email = log.get("User_Email");
|
|
441
|
+
count = ifnull(userDenials.get(email), 0) + 1;
|
|
442
|
+
userDenials.put(email, count);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Alert if any user has 5+ denials
|
|
446
|
+
for each entry in userDenials.entries()
|
|
447
|
+
{
|
|
448
|
+
if (entry.getValue() >= 5)
|
|
449
|
+
{
|
|
450
|
+
sendmail [
|
|
451
|
+
from: zoho.adminuserid
|
|
452
|
+
to: "compliance@cloudstreamsoftware.com"
|
|
453
|
+
subject: "[CRITICAL] SOC2 Alert: Multiple access denials - " + entry.getKey()
|
|
454
|
+
message: entry.getKey() + " has " + entry.getValue() + " denied access attempts in the last hour. Investigate immediately."
|
|
455
|
+
];
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
```
|