Run detection through containment from the screen — ARP/AI, SnapLock, audit logs (part 2 of 3)
A Japanese version of this article is available: 日本語版
Introduction
In Part 1, I looked at putting a file portal on top of the S3 Access Point of Amazon FSx for NetApp ONTAP (hereafter FSx for ONTAP S3 AP, or S3 AP), comparing Amplify Gen2 and Nextcloud as two approaches. The portal at that point stopped at "browse the files" — the moment you wanted to know something about the storage layer, you had to go back to ONTAP System Manager or the CLI.
Once people started using it, the first two things that came back were "I want to check whether ARP has detected anything myself" and "is this snapshot actually locked?" Both requests came from team members outside storage administration, and the sticking point was the same: you cannot check any of it without a VPN connection to the management LIF. So I added ONTAP operations features to the Amplify Gen2 portal, up to the point where health checks and incident first response can be done entirely in a browser.
Here's the conclusion up front:
- ONTAP System Manager-equivalent admin operations can be executed from a browser through AppSync + Lambda
- Separating
storage-adminfrom regular users with Cognito Groups gives you a safe split between read-only viewing and change operations - Managing ransomware response as four states — Detected → Contained → Investigating → Resolved — removes the hesitation from first response
- Turning regulatory retention periods (FISC 7 years / SOX 5 years / HIPAA 6 years) into presets prevents day-count mistakes
In this article, I'll cover the design of the storage operations features embedded in the portal, the ONTAP REST API implementation behind them, and the points I was careful about when handling irreversible operations.
Light theme shown. A dark theme version is available, and every figure is listed in the architecture diagram index.
Relationship to existing tools: This portal makes the same storage management operations previously available only through ONTAP System Manager, ONTAP CLI, or REST API accessible from a browser with Cognito authentication. It is not a replacement for those tools — it's an additional layer that provides browser-based access to the same operations.
The features added are as follows:
- Storage Dashboard: a 4-card health overview
- ARP/AI Incident Lifecycle: managed as four states — Detected → Contained → Investigating → Resolved
- S3 Object Lock Configuration UI: select a bucket, specify a retention mode, apply
-
PHI Guardrail: structurally blocks AI processing for paths such as
/dicom/ - EMS Events: real-time ONTAP alert display
- Regulatory Retention Presets: FISC 7-year / SOX 5-year / HIPAA 6-year
- Welcome Modal: first-time user onboarding
- Audit Log: file access trail via CloudTrail, viewable in the UI
- FlexClone Restore: one-click recovery from snapshots
- Athena Query: SQL analysis on NAS data
Scope: this article is an implementation record of adding "operations features usable by members outside storage administration" to the file portal built in Part 1. Part 3 covers AI agent integration.
Repository: solutions/amplify-portal/
Why Embed Admin Operations in a Portal
ONTAP System Manager is a powerful Web UI, but accessing it requires a VPN connection to the management LIF. When team members outside storage administration (security staff, compliance officers, data protection teams) want to "check ARP status" or "verify whether a snapshot is locked," they have no self-service path.
Motivation for embedding admin operations:
- Security staff should be able to instantly check ransomware detection state and execute containment actions
- Compliance officers should be able to verify retention settings and audit logs themselves
- Operations teams should be able to check ONTAP alerts without opening another tool
Cognito Groups (storage-admin / authenticated) separate authorization — regular users are read-only, only admins can execute changes.
What You Used to Do vs What You Can Do Now
| Operation | Previous Method | Portal Method |
|---|---|---|
| Check ARP threats and contain | VPN to System Manager → Security panel → manual block | Dashboard detection → one-click containment |
| WORM-lock a snapshot | CLI: volume snapshot modify-retention or direct REST API call |
Lock panel → select preset → apply |
| DR failover with SnapMirror | CLI: snapmirror break / snapmirror resync
|
Status list → click action button |
Storage Dashboard — Admin Landing Page
The first thing admins see after login is a 4-card health dashboard. This follows ONTAP System Manager's "dashboard first" pattern.
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 💾 12 │ │ 🛡️ 8 │ │ 🔐 5 │ │ 📊 3.2x │
│ Volumes │ │ARP Protected│ │ Locked Snaps│ │ Efficiency │
│ Avg: 62% │ │✅ No threats│ │ Tamperproof │ │ 69% saved │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
The 4 Cards
| Card | Shows | Navigates to |
|---|---|---|
| Volume Capacity | Volume count + average utilization | Volume Manager |
| ARP/AI Protection | Protected volumes + threat count | ARP Admin |
| Locked Snapshots | Locked snapshot count | Snapshot Admin |
| Storage Efficiency | Dedup/compression ratio + savings | Efficiency Panel |
Implementation
Four APIs fetched in parallel with Promise.allSettled. If one fails (e.g., ARP not configured), remaining cards still render.
const [volResp, arpResp, snapResp, effResp] = await Promise.allSettled([
adminQuery({ action: "listVolumes", params: JSON.stringify({}) }),
adminQuery({ action: "listArpVolumes", params: JSON.stringify({}) }),
protectionQuery({ action: "listSnapshots", params: JSON.stringify({ maxResults: 50 }) }),
adminQuery({ action: "getEfficiencyStats", params: JSON.stringify({}) }),
]);
Why Promise.allSettled over Promise.all: with Promise.all, one failure rejects everything. On a storage dashboard, "ARP not configured" is a normal state, not an error.
ARP/AI Incident Lifecycle
After ONTAP Autonomous Ransomware Protection (ARP/AI) detects a threat, the response flow is managed across 4 states.
State Transitions
🔴 Detected
→ 🟠 Contained
→ 🟡 Investigating
→ 🟢 Resolved
Light theme shown. A dark theme version is available.
What's Recorded at Each State
| State | Timestamp | Additional Data |
|---|---|---|
| Detected | detectedAt | — |
| Contained | containedAt | blockedUsers[], blockedIps[], snapshotName |
| Investigating | — | notes (free text) |
| Resolved | resolvedAt | — |
Containment Actions
Actions executable directly from the portal:
| Action | ONTAP REST API | Effect |
|---|---|---|
| Block SMB User | name-mapping deny (win→unix) | Immediately denies target user's SMB access |
| Block NFS IP | export-policy deny rule | Immediately denies NFS access from target IP |
| Full Containment | snapshot + block + disconnect | Preserves snapshot + blocks all + disconnects sessions |
| Unblock | delete name-mapping/export-policy rules | Recovery after investigation |
This implements the equivalent of NetApp DII Storage Workload Security blocking directly via ONTAP REST API.
Implementation
// useIncidentState hook — persists per-volume in localStorage
export type IncidentState = "none" | "detected" | "contained" | "investigating" | "resolved";
export function useIncidentState(volumeName: string) {
const [incident, setIncident] = useState<IncidentRecord>(() => loadIncident(volumeName));
const markContained = useCallback((snapshot?: string, users?: string[], ips?: string[]) => {
transition("contained", { snapshotName: snapshot, blockedUsers: users || [], blockedIps: ips || [] });
}, [transition]);
// ...
}
The UI displays a state badge with the next action button changing dynamically:
[🔴 Detected] → [Execute Containment] button
[🟠 Contained] → [Start Investigation] button
[🟡 Investigating] → [Resolve] button
[🟢 Resolved] → (complete)
Current limitation: Incident state is stored in localStorage and not shared across browsers. There is also a risk of losing incident state if the browser crashes. DynamoDB persistence is recommended for production use so that multiple members see the same state.
Incident response note: After executing containment actions, integrate with your existing incident runbooks (PagerDuty, OpsGenie, etc.). Portal containment is a first-response action and should be positioned as part of your full incident management workflow.
Security note: Executing containment actions (SMB block, NFS IP block) requires membership in the
storage-admingroup. Unblocking requires the same privilege, so even if a regular user's browser session is compromised, the attacker cannot lift a block. Compromise of astorage-adminaccount itself is guarded by Cognito MFA.Multi-tenant note: When multiple teams (tenants) share the same portal, ensure tenant A cannot view tenant B's ARP alerts by combining Cognito Groups with volume-level access control. In the current implementation, all
storage-admingroup members can view ARP status for all volumes. If tenant isolation is required, consider deploying separate portal instances per SVM.
PHI Guardrail — Structurally Blocking AI Processing
Prevents the "accidentally sent PHI data to an external AI" scenario at the UI level in HIPAA environments.
How It Works
Files in paths containing /dicom/, /phi/, /pii/, /hipaa/, or /protected-health/ have their AI processing button automatically disabled.
const isPhiPath = (path: string): boolean => {
const lower = path.toLowerCase();
return /\/(dicom|phi|pii|hipaa|protected-health)[\/-]/.test(`/${lower}`) ||
lower.startsWith("dicom/") || lower.startsWith("phi/") || lower.startsWith("pii/");
};
UI display:
Normal folder: [⚡ Run AI Processing] ← clickable
PHI folder: [🚫 PHI — AI Blocked] ← disabled, not clickable
Design Intent
- Guardrail, not detect-and-respond: rather than "processed it, then discovered it was PHI," this prevents processing from starting at all
- Cannot be bypassed even by admins: the button itself is disabled regardless of permissions
- Depends on folder naming convention: path-pattern based, so it presupposes organizational folder structure rules
Important limitation: This guardrail blocks based on folder path only — it does NOT scan file contents. A file like
/contracts/sensitive-patient.pdfplaced outside PHI paths will not be blocked. For content-based PHI detection, combine with Bedrock Guardrails (response filtering) described in Part 3. Path guardrail + content filtering gives you ideal 2-layer defense.HIPAA note: Using this portal in a HIPAA environment presupposes a Business Associate Agreement (BAA) with AWS. Cognito, Lambda, S3, Step Functions, and Bedrock are all HIPAA eligible services. The PHI guardrail is an additional UI-level defense — both the BAA and technical controls are required.
S3 Object Lock — WORM Protection for Output Buckets
AI processing results and compliance reports are stored in standard S3 buckets outside FSx for ONTAP. The portal provides a UI to configure S3 Object Lock on these output buckets.
3-Tab Lock Panel
| Tab | Target | Purpose |
|---|---|---|
| ONTAP SnapLock | Volumes | WORM protection for NAS data (shared across NFS/SMB/S3 AP) |
| S3 Object Lock | S3 Buckets | WORM protection for AI processing results |
| Tamperproof Snapshot | Snapshots | Tamper prevention for specific snapshots |
S3 Object Lock Configuration Flow
1. Fetch bucket list → select from dropdown
2. Choose mode:
- Governance: Authorized users can override (recommended for AI output)
- Compliance: No one, including root, can delete until retention expires (regulatory archives)
3. Specify retention days
4. [Apply] sets Object Lock Configuration
When to Use SnapLock vs S3 Object Lock
| Characteristic | ONTAP SnapLock | S3 Object Lock |
|---|---|---|
| Target | Files on NAS volumes | Objects in S3 buckets |
| Access protocols | NFS/SMB/S3 AP | S3 API |
| Use case | Source data WORM protection | AI results/reports protection |
| Regulatory | SEC 17a-4, FISC, HIPAA, NARA | SEC 17a-4, HIPAA |
Combining both achieves "source data AND processing results both tamper-proof."
Compliance framework note: The AWS services used by this portal (Cognito, Lambda, S3, Step Functions, Bedrock, AppSync) are in scope for ISMAP and SOC 2. FedRAMP environments for US government agencies require deployment in AWS GovCloud regions. Confirm compliance requirements with your legal and compliance teams — this portal is a technical implementation pattern and does not provide compliance judgments.
Regulatory Retention Period Presets
The Tamperproof Snapshot lock form offers retention periods as dropdown selections.
Preset List
| Preset | Retention Days | Regulatory Basis |
|---|---|---|
| 30 days | 30 | Short-term validation |
| 90 days | 90 | Quarterly |
| 1 year | 365 | Annual |
| SOX/J-SOX | 1,825 (5 years) | Securities Exchange Act — financial records retention |
| HIPAA | 2,192 (6 years) | Medical records minimum retention |
| FISC | 2,557 (7 years) | Center for Financial Industry Information Systems standard, Chapter 9 |
Compliance note: FISC/SOX/HIPAA presets are provided for technical convenience. Whether the regulatory mapping and retention periods apply to your organization's specific situation should be validated with your legal and compliance teams. Regulatory interpretation varies by industry, business scope, and jurisdiction.
Why Presets Are Needed
SnapLock retention settings are irreversible. Once a snapshot is locked, the retention period cannot be shortened.
- Prevents "how many days is 5 years?" calculation errors
- Each preset shows a tooltip with regulatory basis
- Minimizes risk of incorrect selection (can extend but never shorten)
<option value={1825} title="SOX/J-SOX: Financial records must be retained for 5 years">
1,825 days — SOX/J-SOX (5 years)
</option>
<option value={2192} title="HIPAA: Medical records require minimum 6-year retention">
2,192 days — HIPAA (6 years)
</option>
<option value={2557} title="FISC: Financial institution data requires 7-year retention">
2,557 days — FISC (7 years)
</option>
EMS Events — ONTAP Alert Viewer
Retrieves events from ONTAP's Event Management System (EMS) with severity alert/error/emergency and displays them in the admin panel.
Backend Implementation
def _get_ems_events(http, headers, event):
"""ONTAP REST: GET /api/support/ems/events"""
max_records = min(event.get("maxRecords", 20), 50)
severity_filter = event.get("severity", "alert,error,emergency")
query = f"/support/ems/events?max_records={max_records}"
query += f"&severity={severity_filter}"
query += "&order_by=time desc"
query += "&fields=time,severity,message.name,message.text,node.name"
data = _ontap_request(http, headers, "GET", query)
events = [
{
"time": e.get("time", ""),
"severity": e.get("severity", ""),
"messageName": e.get("message", {}).get("name", ""),
"messageText": e.get("message", {}).get("text", ""),
"node": e.get("node", {}).get("name", ""),
}
for e in data.get("records", [])
]
return {"events": events, "count": len(events)}
Example Events
| Severity | Message Name | Meaning |
|---|---|---|
| emergency | ha.takeover.byPartner | HA partner takeover |
| alert | raid.disk.predictiveFailure | Disk predictive failure |
| error | scsiblade.san.netLIFDown | SAN LIF down |
| alert | arw.volume.attack | ARP detected ransomware attack |
Storage administrators can check recent alerts directly in the portal without accessing ONTAP System Manager or CLI.
Refresh frequency note: EMS events are fetched on demand when the dashboard is displayed (not by periodic polling). If you need real-time alerting, push EMS events via EventBridge + SNS instead (see fsxn-observability-integrations). The portal is for "checking recent events"; for "detecting in real time," consider pairing it with a separate observability stack.
Welcome Modal — First-Time Onboarding
First-time users see a 3-step guided tour.
3 Steps
- 📂 File Browsing — Browse and search NAS files from your browser
- ⚡ AI Processing — Select files and trigger AI/ML workflows
- 🔒 Data Protection — Snapshots, WORM locks, ransomware protection
Implementation
export function WelcomeModal() {
const [dismissed, setDismissed] = useState(() => {
try { return localStorage.getItem("portal-welcome-dismissed") === "true"; }
catch { return false; }
});
if (dismissed) return null;
// 3-step carousel with dot navigation
// "Don't show again" checkbox → localStorage persistence
}
Design Intent
- Standard onboarding pattern in SaaS products
- Often omitted in internal tools, but highly effective for conveying "what this portal can do" in 10 seconds
-
localStoragestate management, works without backend changes
Resource Management — 20-Panel Card-Grid Admin
ONTAP admin operations organized into 5 categories × 20 panels.
Category Structure
| Category | Panels |
|---|---|
| 🗄️ Storage | Volumes / 🧬 FlexClone / ⚡ FlexCache / Qtrees / Quotas / Efficiency |
| 🔐 Access Control | Export Policies / SMB Shares / 👤 Local Users / 🔀 Name Mapping / QoS |
| 🛡️ Data Protection | ARP/AI / Snapshots / SnapLock / 📡 FPolicy / 🦠 Vscan / 🪞 SnapMirror |
| 🖥️ Cluster | 🔗 Peering / 🖥️ Cluster Information |
| 🤖 Services | AI Settings |
Each panel displays as a card grid, clicking navigates to the detail view. Follows System Manager's card-based navigation.
The Cluster category covers the part the AWS Management Console does not expose. Cluster peering and SVM peering had to be done from the ONTAP CLI or by hand-writing REST calls, which is a real operational cost for an AWS-centric team that otherwise never leaves the console.
New Panel Highlights
Vscan — "Zero to Configured" Setup Guidance
Vscan (antivirus scanning) has the highest setup barrier of any ONTAP feature — it requires external Windows/Linux servers and antivirus vendor licenses. When unconfigured, the Vscan panel displays a 5-step guided wizard:
- Vendor selection (6-vendor comparison table with license page links)
- NetApp Antivirus Connector download
- EC2 deployment (architecture diagram + AWS Blog/GitHub samples)
- ONTAP CLI commands (scanner-pool / policy / enable)
- Verification in this panel
Even someone starting from "what is Vscan?" can follow the setup path directly from the portal.
One correction from the first version of this panel: the guidance only rendered while Vscan was disabled, so it disappeared the moment Vscan came up — exactly when you still want the scanner-side steps and the interoperability matrix link. It now stays reachable from a toolbar toggle in both states.
FlexClone — Instant Zero-Copy Clones
Create and split volume clones from the UI for ransomware recovery, forensics, or dev/test. Metadata-only copy completes in seconds with near-zero additional capacity.
SnapMirror — Replication Lifecycle Management
Monitor DR and cross-region replication relationships in the browser and execute actions (sync, break, resync, quiesce, resume, delete). Click a relationship to expand the last 10 transfer records (size, duration, success/failure). Lag times exceeding your RPO target display in red so they are noticed immediately.
DR planning note: SnapMirror Break/Resync operations are executable from the browser, but understand the RPO impact before clicking Break. After a break, the replication relationship is severed and resync requires delta transfer. For production environments, pair the confirmation dialog (implemented) with your team's DR runbook procedures.
FlexCache — Remote Read Cache CRUD
Create FlexCache volumes (async, with prepopulate path support), view the list (origin→cache arrow display), and delete (automated 3-step: unmount→offline→delete). When unconfigured, guidance is displayed with a datalist for selecting origin volumes.
Async polling note: FlexCache creation uses async polling to detect completion. If the user closes the browser during creation, the ONTAP-side operation continues. The created volume appears on the next list refresh — no data loss or inconsistent state results.
Cluster and SVM Peering — the gap the console leaves
Peering is a two-sided operation, and the authentication passphrase has to travel between the two clusters. The panel drives one side at a time.
The prerequisite that trips people up is the intercluster LIF, so it gets its own tab rather than being left as a footnote. Both clusters need at least one in up state, and TCP 11104, 11105 plus ICMP have to be allowed between their addresses — the intercluster LIF addresses, not the management LIF.
The flow is: check the LIFs, create the peer on one cluster with Generate passphrase, then enter that passphrase under Accept on the other. The generated value is shown once — ONTAP returns it in the creation response only, so the panel surfaces it in a banner you have to dismiss deliberately. Lose it and the peer has to be deleted and recreated.
SVM peers come after the cluster peer reaches available, and are accepted on the remote side without a passphrase. An SVM-level SnapMirror additionally needs the source subtype default and the destination dp_destination.
Cluster Information — nodes, licences, LIFs, protocols, DNS, jobs
Four tabs: overview (cluster name and version, nodes, licences), interfaces (LIF list with enable/disable), services (NFS, SMB and S3 state with enable/disable, plus the SVM DNS domains and servers), and jobs.
The overview tab is quieter than that list suggests. On the cluster I tested (ONTAP 9.17.1P7D1) both /cluster/nodes and /cluster/licensing/licenses returned zero records with no error, because AWS manages the cluster rather than the tenant. The first version of the panel rendered that as a bare "No nodes", which reads as a failure, so it now states that an empty list is expected here. The cluster name and ONTAP version come from /cluster and are still populated.
The jobs tab matters more than it looks. FlexCache creation, FlexClone split, SnapMirror transfers and peering all run as asynchronous ONTAP jobs, so this is where their progress and, more usefully, their failure reasons show up.
DNS note: an AD-joined SVM resolves its domain controllers through the servers set here. A wrong value breaks SMB, and on an AD-joined SVM it also makes S3 Access Point data operations fail with
AccessDenied— whileHeadBucketkeeps succeeding, which sends you looking at IAM instead of the file system layer.
Destructive operations are gated in both layers
SnapMirror break, resync and delete, Vscan and FPolicy policy deletion, peer deletion, and disabling a LIF or a protocol all show an inline confirmation row before anything is sent.
The confirmation is not only in the UI. The Lambda refuses the same actions unless confirm=true is present, so a direct call that bypasses the browser is rejected identically. That split matters: a UI-only guard is a suggestion, not a control.
Getting this wrong is instructive. In the first cut, the Vscan and FPolicy delete buttons sent no confirm flag and had no confirmation row, and the handler did not check for one either — while the documentation already claimed the operation was confirm-gated. The button appeared to work and the docs looked right. The fix was to make all three agree, and to pin the contract in tests: for every confirm-gated action, assert it refuses without confirm and succeeds with exactly the parameters the UI sends. The second half of that assertion is the one that would have caught it.
Security Model
| Layer | Implementation |
|---|---|
| Authentication | Cognito User Pool + MFA (TOTP/SMS) |
| Authorization (API) | Cognito Groups (storage-admin / authenticated) |
| Authorization (Files) | S3 AP + UNIX/Windows file system identity |
| Transport encryption | HTTPS (AppSync) + TLS 1.2 (ONTAP REST API) |
| Secrets management | Secrets Manager (ONTAP credentials) |
| Audit | CloudTrail S3 data events |
| WORM | SnapLock (Compliance/Enterprise) + S3 Object Lock |
| Ransomware protection | ONTAP ARP/AI + portal containment actions |
| PHI protection | Path-based guardrail (AI processing block) |
Only users in the storage-admin group can execute admin operations (volume creation, SnapLock configuration, ARP containment, etc.). Regular users are limited to file browsing and AI processing.
Enterprise SSO note: Cognito User Pool supports SAML 2.0 and OIDC federation. To integrate with an existing IdP such as Okta, Azure AD, or Google Workspace, see Cognito's Adding SAML identity providers. Group mapping lets you map IdP groups to the Cognito
storage-admingroup.Infrastructure protection note: Amplify Hosting is served via Amazon CloudFront, so AWS Shield Standard (DDoS protection) is automatically applied. If additional WAF rules are needed, attach AWS WAF to the CloudFront distribution.
Usage Scenarios
Scenario 1: Ransomware Response
1. Storage Dashboard shows 🚨 ARP Threats: 1
2. Navigate to ARP/AI panel → view threat details
3. Click [Contain] → SMB user blocked + snapshot taken
4. State transitions to 🟠 Contained
5. After forensic analysis, [Investigation Complete] → [Resolve]
6. Unblock to resume normal operations
Scenario 2: Compliance Audit
1. Lock panel → SnapLock tab to review Compliance volume list
2. Tamperproof tab to apply FISC 7-year lock to snapshots
3. S3 Object Lock tab to verify output bucket retention settings
4. Audit Trail to review operation history
Scenario 3: Daily Monitoring
1. Storage Dashboard — glance at 4 cards (30 seconds)
2. If any volume exceeds 85% capacity, drill into Volume Manager
3. Check EMS Events for recent alerts
4. No issues → done
Design Trade-offs
| Design Decision | Benefit | Trade-off |
|---|---|---|
| localStorage (Incident State) | Simple deployment | Not shared across browsers; incident state can be lost if the browser crashes. DynamoDB migration recommended for production |
| PHI path regex | Simple, immediate | Requires folder naming convention compliance |
| Generic Dispatch (8 endpoints) | Avoids CFn 1MB limit | IAM policy granularity is coarser |
| VPC split | Cold start optimization | Two types of Lambda required |
| Promise.allSettled (Dashboard) | Resilient to partial failures | Failed cards show 0 |
| Regulatory presets (hardcoded) | Ready to use immediately | Code change needed if regulations update |
Rollback Procedure
Recovery paths if a portal update causes problems:
| Situation | Rollback method |
|---|---|
| Frontend UI issue | One-click revert to the previous build from the Amplify Hosting console |
| Lambda function issue |
git revert + git push triggers automatic redeploy (Amplify Gen2) |
| ONTAP configuration change issue | Restore directly via ONTAP REST API (export-policy, name-mapping, etc.) |
| Cognito configuration change | CDK stack rollback is not available. Revert manually to the previous state |
Because frontend and backend are both under Git management, git revert + git push rolls back immediately. Some ONTAP-side changes (such as enabling SnapLock) are irreversible, so verification before execution matters.
8-Language Support (i18n)
All admin features included, the entire portal supports 8 languages:
| Code | Language |
|---|---|
ja |
日本語 |
en |
English |
ko |
한국어 |
zh-CN |
简体中文 |
zh-TW |
繁體中文 |
fr |
Français |
de |
Deutsch |
es |
Español |
Technical terms (ONTAP, SnapLock, FlexClone, S3 AP, ARP/AI, WORM, FISC, SOX, HIPAA) are not translated. Browser navigator.language auto-detection with instant switching via the header language picker.
Audit Log — Checking "Who Accessed What and When" in the UI
The most frequent request from compliance officers was "I want to check the file access trail myself." Grepping CloudTrail logs from the CLI is not realistic for anyone outside the security team.
The portal's Audit tab runs filtered queries:
| Filter | Example |
|---|---|
| File path | Show only accesses under /contracts/
|
| Event type | READ / WRITE / ALL |
| Time range | 2026-07-01 – 2026-07-28 |
Architecture
AppSync Query → Lambda → Athena SQL → CloudTrail S3 Data Event logs
Light theme shown. A dark theme version is available.
CloudTrail S3 data events are registered as a Glue table and queried with Athena. Results display in table form, and access denials (AccessDenied) are highlighted in red.
Prerequisites
- Enable data events for the S3 AP ARN on a CloudTrail Trail
- Create the Athena table via Glue Crawler or a manual
CREATE TABLE - Set
ATHENA_AUDIT_DATABASE,ATHENA_AUDIT_TABLE, andATHENA_AUDIT_OUTPUTas Lambda environment variables
If these are unconfigured, the UI displays "configuration required" guidance with the setup steps. The design treats this as onboarding rather than an error.
Data Retention
Query results are stored in the Athena workgroup output location (S3). Retention of the original CloudTrail logs is controlled by the S3 bucket lifecycle policy on the Trail's bucket. Set retention periods such as FISC 7 years or HIPAA 6 years according to your audit requirements.
Cost note: If you store audit trails in DynamoDB, storage costs grow in large environments. Set a retention policy (TTL) and archive old records to S3 Glacier. CloudTrail log retention is controlled separately via the Trail's lifecycle policy.
FlexClone Restore — Instant Recovery from Snapshots
When recovering from ransomware damage or accidental deletion, the requirement is "I want to go back to the snapshot from before the infection." Previously this meant creating a FlexClone from the CLI and attaching an S3 AP as a sequence of manual operations.
In the portal, from the 📸 button on the Files tab:
1. Enter the snapshot name (e.g., daily.2026-07-18_0010)
2. Click [Clone & Attach]
3. Step Functions automatically runs FlexClone creation → S3 AP attach
4. FlexClone information appears on the Results tab
FlexClone Status Display
🔄 FlexClone Volume
Volume: clone-uc6-20260718-abc123
Parent: vol_data
Status: 🟢 online
Created: 2026-07-18 15:00:00
Size: 128 MB
S3 AP: clone-uc6-abc123-s3alias
Use Cases
| Scenario | Purpose |
|---|---|
| Ransomware recovery | Immediate access to a pre-infection snapshot |
| Forensics | Isolate a point-in-time copy for investigation |
| Testing | Validate against a clone without touching production data |
FlexClone is a metadata-only copy, so it completes in seconds with near-zero additional capacity. Differential capacity is consumed only as writes occur.
Accessibility note: Confirmation dialogs for FlexCache deletion and volume deletion are displayed inline. For screen reader users, confirmation messages are announced via
role="alertdialog"andaria-describedby. Keyboard navigation (Tab/Enter/Escape) is fully supported.Throughput note: A FlexClone volume shares the throughput budget with its parent volume. If clones are used actively in parallel in production, account for the performance impact on the parent volume. For read-oriented uses such as forensics this is typically not a concern.
Athena Query — SQL Analytics on NAS Data
When files on FSx for ONTAP are cataloged via Glue Crawler, you can run SQL queries using Athena. The portal's "Analytics" tab lets you enter a database name and SQL, and execute directly.
There is no need to open the AWS Athena console separately — everything completes inside the portal.
UI Layout
┌──────────────────────────────────────────────────┐
│ SQL Query (Athena) [default ] │
├──────────────────────────────────────────────────┤
│ 💡 How to use: catalog files on FSx for ONTAP │
│ with Glue Crawler, then analyze them here with │
│ SQL. │
│ ▸ 📝 View query examples (collapsible) │
├──────────────────────────────────────────────────┤
│ SHOW TABLES IN default │
│ │
│ [Run query] │
└──────────────────────────────────────────────────┘
Usage Flow
-
First time: run
SHOW TABLES IN defaultto discover available tables - Once you know table names: execute specific SELECT queries
- Results: displayed in table form
Practical Query Examples
-- Find large files (capacity planning)
SELECT key, size FROM default.s3_objects
WHERE size > 1000000000
ORDER BY size DESC LIMIT 20
-- Total size of a specific folder (project sizing)
SELECT SUM(size) as total_bytes
FROM default.s3_objects
WHERE key LIKE 'engineering/%'
-- Files modified in last 7 days (change tracking)
SELECT key, last_modified
FROM default.s3_objects
WHERE last_modified > current_date - interval '7' day
The portal UI includes an expandable "View query examples" section, so even users unfamiliar with SQL can get started by copy-pasting.
Not just "browse the files" but "ask questions of the data" — directly from the portal.
File Formats Glue Crawler Recognizes
| Category | Formats |
|---|---|
| Structured data | CSV, TSV, JSON, Parquet, ORC, Avro |
| Logs | Apache/NGINX logs, CloudTrail JSON |
| Documents | — (text extraction requires Textract or Bedrock) |
CAD/EDA binary files cannot be cataloged by Glue Crawler, but file metadata (size, last modified, path) is still retrievable.
Athena Cost Optimization Tips
Athena bills on the volume of data scanned ($5/TB). Ways to keep costs down:
- Date partitions (
year=/month=/day=) reduce scan volume when a WHERE clause narrows the time range - With columnar formats such as Parquet/ORC, specifying only the columns you need instead of
SELECT *reduces cost - Make it a habit to always add a
LIMITclause to exploratory queries - Setting a query limit on the Athena workgroup (for example 10 GB/day) caps unexpected scan volume
Cost Awareness
Rough additional cost if every feature in this article is enabled:
| Resource | Estimate | Notes |
|---|---|---|
| VPC Lambda (Admin) | ~$5/month | Depends on invocation frequency. Negligible for daily checks |
| CloudTrail S3 Data Events | ~$10–$50/month | Proportional to file access volume |
| Athena queries | $5/TB scanned | Audit queries scan little; partitions reduce it further |
| Secrets Manager | $0.40/secret/month | One ONTAP credential |
| DemoMode | $0 | No FSx for ONTAP needed. Runs on S3 alone |
The cost of FSx for ONTAP itself (~$194/month at 128 MBps) was covered in Part 1. The portal's incremental cost depends on usage frequency, but evaluating in DemoMode adds nothing.
Deployment Time Estimates
| Step | Time | Prerequisite |
|---|---|---|
| DemoMode deploy | ~15 min | Amplify CLI installed |
| Add VPC + ONTAP connectivity | ~30 min | FSx for ONTAP file system running |
| Audit Log configuration | ~20 min | CloudTrail + Glue Crawler |
| Full feature deploy | ~60 min | All of the above |
What to Expect After Deployment
- Once the DemoMode deploy completes, the portal is reachable at
https://<branch>.amplifyapp.com. Cognito sign-up → log in → the file list shows test data from the S3 bucket - Once VPC connectivity is added, the Storage Dashboard shows actual volume counts and utilization, and protected volumes appear in the ARP panel
- Once all features are deployed, the Audit Log tab can run CloudTrail queries and the Lock panel shows SnapLock/Object Lock settings
Environment Variables and Configuration Parameters
| Parameter | Description | Example Value |
|---|---|---|
DEMO_MODE |
Run without FSx for ONTAP |
true (PoC) / false (production) |
ONTAP_SECRET_ARN |
Secrets Manager ARN for ONTAP credentials | arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:fsxn-admin-XXXXXX |
ATHENA_AUDIT_DATABASE |
Glue database name for audit queries | cloudtrail_logs |
ATHENA_AUDIT_TABLE |
Athena table name for audit queries | s3_data_events |
ATHENA_AUDIT_OUTPUT |
S3 location for Athena query results | s3://my-audit-results/athena-output/ |
PoC → Production Checklist
After evaluating in DemoMode, use this checklist when moving to production connectivity:
| Category | Verification |
|---|---|
| Network | VPC subnet contains the FSx for ONTAP ENIs; Security Group allows TCP 443 (management LIF). Note: NFS (2049) / SMB (445) are for data access and are not needed for the portal's admin operations |
| Auth | Cognito User Pool MFA enabled; storage-admin group members confirmed |
| Secrets | ONTAP credentials registered in Secrets Manager |
| Audit | CloudTrail Trail with S3 data events enabled for the S3 AP ARN |
| Backup |
portal-config.ts values in Git (secrets excluded) |
| Cost | CloudTrail data event estimate confirmed (proportional to access volume) |
| SSO | (Optional) SAML/OIDC federation configured if using an enterprise IdP |
Role-Based Documentation (8 Languages × 3 Guides)
Alongside the feature additions, role-specific documentation was built. Based on usability principles (visibility of system status, task-oriented structure, ease of error recovery), 3 guides are provided in 8 languages:
| Guide | Target Role | Key Content |
|---|---|---|
| User Guide | End users | Sign in, file operations, AI processing, FAQ |
| Compliance Guide | Security/Compliance officers | ARP verification, WORM checks, audit trail, PHI guardrail validation, regulatory mapping (FISC/HIPAA/SOX/NIST/ISO) |
| Quick Reference | All roles | 1-page cheat sheet (navigation, tasks by role, status indicators, troubleshooting) |
Supported languages: 日本語, English, 한국어, 简体中文, 繁體中文, Français, Deutsch, Español
Design choices for the compliance officer guide:
- All tasks executable without
storage-adminprivileges (read-only access is sufficient) - Each task includes "Evidence for auditors" instructions
- Explicit "What you cannot do" escalation table showing who to contact
FlexCache / SnapMirror Management
Direct ONTAP REST API Operations from the Browser
FlexCache, FlexClone, SnapMirror, Vscan, FPolicy, cluster and SVM peering, and the cluster services are all managed through the browser UI — 110 actions in total. A VPC-deployed Lambda connects to the FSx for ONTAP management endpoint via HTTPS, calling ONTAP REST API with credentials from Secrets Manager.
Browser → AppSync (Cognito auth) → Lambda (in VPC) → ONTAP REST API
↓
Secrets Manager
(fsxadmin credentials)
Light theme shown. A dark theme version is available.
FlexCache Create UI
Select the origin volume from a dropdown (datalist), specify cache name, size, and prepopulate paths, then create. The experience mirrors ONTAP System Manager — accessible from any browser with Cognito authentication.
SnapMirror Lifecycle Management
The replication relationship list shows state badges (✅ Snapmirrored / 🔴 Broken-off / 🔄 Transferring / ⏸️ Paused) with context-sensitive action buttons. DR failover (Break → Resync) is fully accessible from the browser. Lag times exceeding your RPO target display in red with a ⚠️ RPO warning.
Lessons Learned
Async Operations with return_timeout=0
FlexCache creation is an asynchronous ONTAP job taking 30-120 seconds. By specifying return_timeout=0, ONTAP returns immediately with 202 Accepted + job UUID, preventing Lambda timeout. The UI auto-refreshes the list at 10s/30s/60s intervals.
One Wrong Field Name Empties the Whole List
The SnapMirror list was requesting fields=...,last_transfer_type,last_transfer_size. last_transfer_size is not a field on /snapmirror/relationships, and ONTAP rejects the entire request when a single field name is unknown:
The value "last_transfer_size" is invalid for field "fields" (<field,...>)
So every relationship vanished — not with a visible error, but as an empty list. What made this survive the test suite is worth noting: the mock ONTAP in the unit tests returns records regardless of which fields are requested, so a test that asserts on the mapped response passes either way. The fix was to assert on the outgoing query string instead. Per-transfer byte counts were already available from /snapmirror/relationships/{uuid}/transfers, so nothing was lost by dropping the field.
Automated 3-Step FlexCache Deletion
Mounted FlexCache volumes cannot be deleted directly. The portal automates:
- Remove junction path (unmount)
- Set volume offline
- Delete FlexCache (async)
Credential Synchronization
When changing the fsxadmin password, update both the FSx for ONTAP API and Secrets Manager simultaneously. Updating only one side causes authentication failures that can trigger ONTAP's account lockout mechanism. Recovery: aws fsx update-file-system password reset → Secrets Manager sync.
FSx for ONTAP Specifics
| Item | FSx for ONTAP | On-prem ONTAP |
|---|---|---|
| Aggregate specification | Not needed (auto-selected) | Required |
| SVM creation | AWS API only | CLI/REST available |
| Intra-cluster FlexCache | Supported (no peering needed) | Supported |
| fsxadmin password reset | aws fsx update-file-system |
security login password |
Coexistence with Existing Tools
This portal is not a replacement for ONTAP System Manager, ONTAP CLI, or REST API. It makes a subset of those operations accessible from a browser UI with Cognito authentication — an additional management layer, not a substitute.
| Scenario | Portal's Role |
|---|---|
| Using cloud file-sharing SaaS | AI processing and audit for large-scale NAS data only |
| Running self-hosted file sharing | Add S3 AP as External Storage for management operations |
| Using hybrid file services | Add data protection and ARP/AI visibility layer |
| Using ONTAP System Manager daily | Provide visibility to non-storage-admin team members |
The portal provides a management layer for NAS-specific capabilities (Snapshot, FlexClone, FlexCache, SnapMirror, ARP/AI) accessible from the browser. Adoption can be incremental — management operations only, AI processing only, or the full suite — depending on existing workflows.
PoC → Production Migration Flow
After evaluating in DemoMode (no FSx for ONTAP required), migrate to production connectivity in three phases:
┌────────────────┐ ┌────────────────┐ ┌────────────────┐
│ Phase 1: PoC │ │ Phase 2: VPC │ │ Phase 3: Prod │
│ (~15 min) │ │ Connectivity │ │ Hardening │
│ │ │ (~30 min) │ │ (~60 min) │
│ DemoMode=true │ ──→ │ ONTAP mgmt LIF │ ──→ │ Least-privilege│
│ S3 bucket │ │ Secrets Mgr │ │ MFA required │
│ Auth: Cognito │ │ VPC Endpoint │ │ WAF added │
│ │ │ │ │ Audit enabled │
└────────────────┘ └────────────────┘ └────────────────┘
Light theme shown. A dark theme version is available.
| Phase | Time | Added Cost | What You Get | What Changes | What Stays the Same |
|---|---|---|---|---|---|
| 1 (PoC) | ~15 min | $0 | UI/UX evaluation, AI processing test | Nothing (fresh deploy) | — |
| 2 (VPC) | ~30 min | Lambda VPC ~$5/mo | ONTAP admin operations, dashboard | Lambda VPC config added, Secrets Manager registered | Frontend UI, Cognito settings, S3 bucket config |
| 3 (Prod) | ~60 min | CloudTrail ~$10–50/mo | Audit, WAF, MFA, least-privilege IAM | IAM policy tightening, WAF attachment, MFA enforcement | Application code, ONTAP connection settings |
Post-Deployment Verification
Expected state after each phase completes:
- After Phase 1: you can log in to the portal, and DemoMode file listing and AI processing tests work. The Storage Dashboard still shows "not connected"
- After Phase 2: the Storage Dashboard shows actual volume information, and ONTAP data appears in the ARP panel and EMS Events
- After Phase 3: login is impossible without MFA, CloudTrail records all operations, and WAF applies rate limiting
Irreversible operations warning: The following operations cannot be undone once executed. Verify your organization's policies before enabling them in Phase 2+:
- SnapLock Compliance enablement: Volume SnapLock type cannot be changed after creation
- Tamperproof Snapshot retention period: Once set, the period cannot be shortened (only extended)
- S3 Object Lock Compliance mode: No one, including root, can delete objects until retention expires
For detailed migration steps, see the PoC → Production Guide.
Authorization Model (PoC → Production)
| Item | PoC | Production |
|---|---|---|
| AppSync auth | allow.authenticated() |
allow.groups(["storage-admin"]) |
| IAM resource scope | "*" |
Specific ARN patterns |
| generateClient |
authMode: "userPool" required |
Same |
In Amplify Gen2 with multiple auth providers, generateClient() must explicitly specify authMode: "userPool" to ensure the Cognito token is sent to AppSync. This is a recommended pattern per official documentation.
Resources
- GitHub: solutions/amplify-portal/
- User Guide (8 languages)
- Compliance Guide (8 languages)
- Quick Reference (8 languages)
- Implementation Guide
- Getting Started Guide
- Admin Demo Guide
- AI Agent Demo Guide
- Security Review
- PoC → Production Guide
- Scaling Guide
- Accessibility Statement
- AWS: ONTAP ARP/AI
- AWS: S3 Object Lock
- Part 1: Adding a File Portal to FSx for ONTAP S3 AP
- Part 3: Embedding AI Agents into a File Portal
Summary and Next Steps
Building on the file portal from Part 1, ONTAP management operations and data protection features were embedded:
| Feature | What it enables |
|---|---|
| Storage Dashboard | Health at a glance immediately after login |
| Incident Lifecycle | Ransomware response with state management |
| PHI Guardrail | Structurally prevents AI processing of regulated data |
| S3 Object Lock | Tamper prevention for AI results, configurable from UI |
| EMS Events | ONTAP alerts without CLI |
| Retention Presets | Just pick the regulation, get the right retention |
| Audit Log | "Who accessed what and when" — self-service for compliance |
| FlexClone Restore | Recover from snapshot in seconds |
| FlexCache CRUD | Create/delete read cache volumes from browser |
| SnapMirror Lifecycle | Sync, break, resync, quiesce — DR from a browser |
| Athena Query | Ask SQL questions against NAS data |
| Welcome Modal | First-time users productive in 10 seconds |
From a portal that "just browses files" to one that "completes storage operations from the web." Daily monitoring and incident first response now finish in the browser without accessing ONTAP System Manager or CLI.
All code is available in the GitHub repository.
As a next step, after running DemoMode using the instructions in Part 1, try adding the VPC configuration to enable ONTAP connectivity. That gets you to a state where every feature in this article is usable. Migration details are collected in the PoC → Production Guide.
In Part 3, I'll write about embedding AI agents into this portal — completing file operations, analysis, and admin operations in natural language.
I hope this post helps someone out there.
See you next time.














Top comments (0)