From 31f62535ea1340dac9cc3fd3ee701e1673082b5f Mon Sep 17 00:00:00 2001 From: Tay Caliguiri Date: Thu, 14 May 2026 18:21:27 -0400 Subject: [PATCH 1/4] Add FSAA DC schema documentation for Access Analyzer 12.0 Adds full schema documentation set for the File System Access Analyzer Data Collector under admin/schema/fsaadc/: ERD, core tables, views, enumeration, functions, index reference, and foreign key reference pages, plus _category_.json sidebar files. Updates schema overview page to include the FSAA DC section below SQL DC. Generated with AI Co-Authored-By: Claude Code --- .../12.0/admin/schema/fsaadc/_category_.json | 10 + .../schema/fsaadc/coretables/_category_.json | 10 + .../schema/fsaadc/coretables/overview.md | 966 ++++++++++++++++++ .../schema/fsaadc/enumeration/_category_.json | 10 + .../schema/fsaadc/enumeration/overview.md | 96 ++ .../admin/schema/fsaadc/erd/_category_.json | 10 + .../12.0/admin/schema/fsaadc/erd/overview.md | 178 ++++ .../schema/fsaadc/fkreference/_category_.json | 10 + .../schema/fsaadc/fkreference/overview.md | 87 ++ .../schema/fsaadc/functions/_category_.json | 10 + .../admin/schema/fsaadc/functions/overview.md | 216 ++++ .../fsaadc/indexreference/_category_.json | 10 + .../schema/fsaadc/indexreference/overview.md | 75 ++ .../12.0/admin/schema/fsaadc/overview.md | 111 ++ .../admin/schema/fsaadc/views/_category_.json | 10 + .../admin/schema/fsaadc/views/overview.md | 551 ++++++++++ .../12.0/admin/schema/overview.md | 11 + 17 files changed, 2371 insertions(+) create mode 100644 docs/accessanalyzer/12.0/admin/schema/fsaadc/_category_.json create mode 100644 docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/_category_.json create mode 100644 docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/overview.md create mode 100644 docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/_category_.json create mode 100644 docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/overview.md create mode 100644 docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/_category_.json create mode 100644 docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/overview.md create mode 100644 docs/accessanalyzer/12.0/admin/schema/fsaadc/fkreference/_category_.json create mode 100644 docs/accessanalyzer/12.0/admin/schema/fsaadc/fkreference/overview.md create mode 100644 docs/accessanalyzer/12.0/admin/schema/fsaadc/functions/_category_.json create mode 100644 docs/accessanalyzer/12.0/admin/schema/fsaadc/functions/overview.md create mode 100644 docs/accessanalyzer/12.0/admin/schema/fsaadc/indexreference/_category_.json create mode 100644 docs/accessanalyzer/12.0/admin/schema/fsaadc/indexreference/overview.md create mode 100644 docs/accessanalyzer/12.0/admin/schema/fsaadc/overview.md create mode 100644 docs/accessanalyzer/12.0/admin/schema/fsaadc/views/_category_.json create mode 100644 docs/accessanalyzer/12.0/admin/schema/fsaadc/views/overview.md diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/_category_.json b/docs/accessanalyzer/12.0/admin/schema/fsaadc/_category_.json new file mode 100644 index 0000000000..53a2e95a33 --- /dev/null +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "File System Access Analyzer DC Schema", + "position": 20, + "collapsed": true, + "collapsible": true, + "link": { + "type": "doc", + "id": "overview" + } +} diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/_category_.json b/docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/_category_.json new file mode 100644 index 0000000000..e390b2c64a --- /dev/null +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Core Data Collection Tables", + "position": 20, + "collapsed": true, + "collapsible": true, + "link": { + "type": "doc", + "id": "overview" + } +} diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/overview.md new file mode 100644 index 0000000000..97aae1b058 --- /dev/null +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/overview.md @@ -0,0 +1,966 @@ +# Core Data Collection Tables + +The FSAA DC schema contains 47 core tables populated by four collector modules: the File System Access Analyzer (`SA_FSAA_`), the File System Activity Collector (`SA_FSAC_`), the Sensitive Data / DLP collector (`SA_FSDLP_`), and the DFS Namespace collector (`SA_FSDFS_`). All `SA_FSAA_*` tables are partitioned by `HOST INT` (FK → `SA_FSAA_Hosts.ID`) with `ON DELETE CASCADE` so that removing a host purges its entire data set. + +## FSAA Tables + +### SA_FSAA_SchemaVer {#sa_fsaa_schemaver} + +Single-row table holding the FSAA schema version string. The CREATE-Schema job clears and re-inserts the version on every run. Used by upgrades to decide whether to apply migrations. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| SchemaVer | varchar | 64 | No | | | | Schema version (current value `8.0.17`) | + +**Primary Key:** None +**Foreign Keys:** None +**Indexes:** None + +### SA_FSAA_Hosts {#sa_fsaa_hosts} + +Registry of every host scanned by FSAA. One row per host. The integer `ID` is the FK target for every other FSAA table's `HOST` column. `USN`/`AccessUSN`/`ActivityUSN`/`DLPUSN` are per-scan-type Update Sequence Numbers used by the C# importer to detect deltas; the matching `*GUID` columns identify the SQLite cache that produced the last upload. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| ID | int | | No | PK | | IDENTITY(1,1) | Surrogate host ID — referenced by every FSAA table | +| HOST | nvarchar | 64 | No | | | | Host name (NetBIOS/FQDN). Has unique constraint | +| SAConsole | nvarchar | 64 | No | | | | Console host that initiated the scan | +| ScanTime | datetime | | No | | | | Time of most recent scan | +| GUID | varchar | 38 | No | | | `''` | Top-level scan correlation GUID | +| USN | int | | No | | | `-1` | Top-level Update Sequence Number for the structural scan | +| AccessUSN | int | | No | | | `-1` | USN tracking the latest Access (FSAA) data import | +| AccessGUID | varchar | 38 | No | | | `''` | Correlation GUID for the latest Access scan | +| ActivityUSN | int | | No | | | `-1` | USN tracking the latest Activity (FSAC) data import | +| ActivityGUID | varchar | 38 | No | | | `''` | Correlation GUID for the latest Activity scan | +| DLPUSN | int | | No | | | `-1` | USN tracking the latest DLP scan | +| DLPGUID | varchar | 38 | No | | | `''` | Correlation GUID for the latest DLP scan | +| LastScanHost | nvarchar | 64 | Yes | | | | Hostname of machine that performed the last scan | + +**Primary Key:** `PK_SA_FSAA_Hosts` — clustered on `(ID)` +**Foreign Keys:** None +**Indexes:** `UQ_SA_FSAA_Hosts_HOST` — unique nonclustered on `(HOST)` + +### SA_FSAA_ImportHistory {#sa_fsaa_importhistory} + +Append-only history of every successful data import for each host. One row per host per import per scan type. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | FK → SA_FSAA_Hosts.ID | | Host that the import covered | +| GUID | varchar | 38 | No | | | | Correlation GUID for the imported scan | +| USN | int | | No | | | | USN observed at import time | +| ScanType | varchar | 32 | No | | | | One of `Access`, `Activity`, `DLP` | +| ImportTime | datetime | | No | PK | | `CURRENT_TIMESTAMP` | When the import ran | + +**Primary Key:** `PK_SA_FSAA_ImportHistory` — clustered on `(HOST, ImportTime)` +**Foreign Keys:** `FK_SA_FSAA_ImportHistory_HOST` — `(HOST) → SA_FSAA_Hosts(ID) ON DELETE CASCADE` +**Indexes:** None beyond the clustered PK + +### SA_FSAA_Trustees {#sa_fsaa_trustees} + +Every distinct security principal observed in ACLs on a host, identified by `(HOST, ID)`. Holds only the SID and `TrusteeType` enumeration; human-readable name fields live in `SA_FSAA_LocalTrustees` for local accounts, or are looked up from the AD inventory at view time. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | FK → SA_FSAA_Hosts.ID | | Host partition | +| ID | int | | No | PK | | | Per-host trustee ID | +| SID | varchar | 184 | No | | | | Security identifier (string form, e.g. `S-1-5-21-...`) | +| TrusteeType | smallint | | No | | | | See [TrusteeType enumeration](../enumeration/overview.md#trusteetype) | + +**Primary Key:** `PK_SA_FSAA_Trustees` — clustered on `(HOST, ID)` +**Foreign Keys:** `FK_SA_FSAA_Trustees_HOST` — `(HOST) → SA_FSAA_Hosts(ID) ON DELETE CASCADE` +**Indexes:** None beyond the clustered PK + +### SA_FSAA_LocalTrustees {#sa_fsaa_localtrustees} + +Subset of `SA_FSAA_Trustees`: the local accounts and groups that exist on the scanned host. Adds NT-style domain/name and display name. `(HOST, ID)` is a foreign key into `SA_FSAA_Trustees`. `IsDisabled` is stored as `'Y'`/`'N'`. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | FK → SA_FSAA_Trustees.HOST | | Host partition | +| ID | int | | No | PK | FK → SA_FSAA_Trustees.ID | | Trustee ID — must exist in `SA_FSAA_Trustees` | +| NTDomain | nvarchar | 128 | Yes | | | | Domain portion of NT-style name | +| NTName | nvarchar | 256 | Yes | | | | SAM account name | +| DisplayName | nvarchar | 256 | Yes | | | | Display name | +| SID | varchar | 184 | No | | | | SID (denormalized copy from `SA_FSAA_Trustees`) | +| TrusteeType | smallint | | No | | | | See [TrusteeType enumeration](../enumeration/overview.md#trusteetype) | +| IsDisabled | varchar | 2 | No | | | | `'Y'` / `'N'` | +| USN | int | | No | | | `-1` | USN at last sighting | +| DeletedUSN | int | | Yes | | | | USN when the principal was removed (NULL = still present) | + +**Primary Key:** `PK_SA_FSAA_LocalTrustees` — clustered on `(HOST, ID)` +**Foreign Keys:** `FK_SA_FSAA_LocalTrustees_ID` — `(HOST, ID) → SA_FSAA_Trustees(HOST, ID) ON DELETE CASCADE` +**Indexes:** None beyond the clustered PK + +### SA_FSAA_TrusteeEquivalence {#sa_fsaa_trusteeequivalence} + +Group-membership edges between local trustees on the host. Each row is a `(group → member)` pair, where `EquivalentTrusteeID` is the group and `TrusteeID` is the member. Used to expand local-group memberships during effective-access calculations. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| TrusteeID | int | | No | PK | FK → SA_FSAA_Trustees.ID | | Member trustee | +| EquivalentTrusteeID | int | | No | PK | FK → SA_FSAA_LocalTrustees.ID | | Group (local trustee) the member belongs to | + +**Primary Key:** `PK_SA_FSAA_TrusteeEquivalence` — clustered on `(HOST, TrusteeID, EquivalentTrusteeID)` +**Foreign Keys:** +- `FK_SA_FSAA_TrusteeEquivalence_TrusteeID` — `(HOST, TrusteeID) → SA_FSAA_Trustees(HOST, ID)` +- `FK_SA_FSAA_TrusteeEquivalence_EquivalentTrusteeID` — `(HOST, EquivalentTrusteeID) → SA_FSAA_LocalTrustees(HOST, ID) ON DELETE CASCADE` + +**Indexes:** `SA_FSAA_TrusteeEquivalence_Group_IDX` — nonclustered on `(HOST, EquivalentTrusteeID)` INCLUDE `(TrusteeID)` + +### SA_FSAA_Rights {#sa_fsaa_rights} + +Permission-entry table. Every distinct ACL is given a `RightsProxyID`; resources sharing an identical ACL share one `RightsProxyID`, deduplicating storage dramatically. Each row is one access-control entry: a `TrusteeID` plus its allow/deny rights broken down by direct/inherited and by simplified bitmask vs. full Windows mask. Created with `WITH (DATA_COMPRESSION = ROW)` on Enterprise editions. + +The `AllowRights`/`DenyRights` columns use the simplified six-bit FSAA representation — see the [Rights Bitmask enumeration](../enumeration/overview.md#rights-bitmask). The `*Mask` columns hold the full Windows access mask. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| RightsProxyID | int | | No | PK | | | Deduplication key — multiple resources may share one proxy | +| TrusteeID | int | | No | PK | FK → SA_FSAA_Trustees.ID | | The principal this ACE applies to | +| AllowRights | smallint | | No | | | | Combined direct+inherited allow bits | +| DenyRights | smallint | | No | | | | Combined direct+inherited deny bits | +| DirectAllowRights | smallint | | No | | | | Direct (non-inherited) allow bits | +| DirectDenyRights | smallint | | No | | | | Direct deny bits | +| InheritedAllowRights | smallint | | No | | | | Inherited allow bits | +| InheritedDenyRights | smallint | | No | | | | Inherited deny bits | +| AllowMask | int | | No | | | | Full Windows allow access mask | +| DenyMask | int | | No | | | | Full Windows deny access mask | +| DirectAllowMask | int | | No | | | | Direct allow mask | +| DirectDenyMask | int | | No | | | | Direct deny mask | +| InheritedAllowMask | int | | No | | | | Inherited allow mask | +| InheritedDenyMask | int | | No | | | | Inherited deny mask | + +**Primary Key:** `PK_SA_FSAA_Rights` — clustered on `(HOST, RightsProxyID, TrusteeID)` +**Foreign Keys:** `FK_SA_FSAA_Rights_TrusteeID` — `(HOST, TrusteeID) → SA_FSAA_Trustees(HOST, ID)` +**Indexes:** None beyond the clustered PK + +### SA_FSAA_Tags {#sa_fsaa_tags} + +Distinct file tag values per host. Used in a two-level dedup pattern: `Tags` holds the unique tag string, `TagKeys`/`TagProxies` define a multi-tag set, and `Resources.TagProxyID` references a particular set. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | FK → SA_FSAA_Hosts.ID | | Host partition | +| TagID | int | | No | PK | | | Per-host tag ID | +| Tag | nvarchar | MAX | No | | | | Tag string (e.g. an Azure Information Protection label or custom tag) | +| Source | tinyint | | No | | | `0` | Tag source | + +**Primary Key:** `PK_SA_FSAA_Tags` — clustered on `(HOST, TagID)` +**Foreign Keys:** `FK_SA_FSAA_Tags_HOST` — `(HOST) → SA_FSAA_Hosts(ID) ON DELETE CASCADE` +**Indexes:** None beyond the clustered PK + +### SA_FSAA_TagKeys {#sa_fsaa_tagkeys} + +Defines a "tag set" identity. Each `TagProxyID` represents a unique combination of tag values shared by one or more resources. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | FK → SA_FSAA_Hosts.ID | | Host partition | +| TagProxyID | int | | No | PK | | | Identifier for the tag set | + +**Primary Key:** `PK_SA_FSAA_TagKeys` — clustered on `(HOST, TagProxyID)` +**Foreign Keys:** `FK_SA_FSAA_TagKeys_HOST` — `(HOST) → SA_FSAA_Hosts(ID) ON DELETE CASCADE` +**Indexes:** None beyond the clustered PK + +### SA_FSAA_TagProxies {#sa_fsaa_tagproxies} + +Membership of `Tags` in a `TagKeys` set: each row links one tag to one tag-proxy. A resource's `TagProxyID` points at a row in `TagKeys`; joining through `TagProxies` yields the list of tags applied. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | FK → SA_FSAA_Hosts.ID | | Host partition | +| TagProxyID | int | | No | PK | FK → SA_FSAA_TagKeys.TagProxyID | | Tag set | +| TagID | int | | No | PK | FK → SA_FSAA_Tags.TagID | | Tag in the set | + +**Primary Key:** `PK_SA_FSAA_TagProxies` — clustered on `(HOST, TagProxyID, TagID)` +**Foreign Keys:** +- `FK_SA_FSAA_TagProxies_HOST` — `(HOST) → SA_FSAA_Hosts(ID) ON DELETE CASCADE` +- `FK_SA_FSAA_TagProxies_TagProxyID` — `(HOST, TagProxyID) → SA_FSAA_TagKeys(HOST, TagProxyID)` +- `FK_SA_FSAA_TagProxies_TagID` — `(HOST, TagID) → SA_FSAA_Tags(HOST, TagID)` + +**Indexes:** None beyond the clustered PK + +### SA_FSAA_Resources {#sa_fsaa_resources} + +The structural backbone — every share, folder, and file the DC has seen on the host, plus its parent linkage, owner, ACL pointer, gate pointer, tag pointer, sizing, and timestamps. This is the largest table in the schema by row count and is created `WITH (DATA_COMPRESSION = ROW)` on Enterprise editions. + +`RightsProxyID`, `GatesProxyID`, and `TagProxyID` are logical (un-enforced) denormalized pointers; no FK constraints exist on them so that bulk imports can stage rows in any order. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | FK → SA_FSAA_Hosts.ID | | Host partition | +| ID | bigint | | No | PK | | | Per-host resource ID (bigint to support very large file systems) | +| ParentResourceID | bigint | | Yes | | FK → SA_FSAA_Resources.ID | | Parent folder/share. NULL = root | +| Name | nvarchar | 2000 | No | | | | Leaf name (folder/file name; share name for shares) | +| ResourceType | tinyint | | No | | | | See [ResourceType enumeration](../enumeration/overview.md#resourcetype) | +| OwnerID | int | | Yes | | FK → SA_FSAA_Trustees.ID | | Resource owner trustee | +| RightsProxyID | int | | Yes | | | | Logical pointer into `SA_FSAA_Rights` (no enforced FK; NULL = inherited from parent) | +| GatesProxyID | bigint | | Yes | | | | Logical pointer into `SA_FSAA_GatesProxy` (no enforced FK) | +| NestedLevel | int | | No | | | | Depth in the resource tree (0 = root) | +| Size | bigint | | Yes | | | | Aggregated file-content size | +| LastModified | datetime | | Yes | | | | NTFS last-modified timestamp | +| LastAccessed | datetime | | Yes | | | | NTFS last-accessed timestamp | +| Created | datetime | | Yes | | | | NTFS creation timestamp | +| TagProxyID | int | | Yes | | | | Logical pointer into `SA_FSAA_TagKeys` (no enforced FK) | +| USN | int | | No | | | `-1` | Structural USN — last seen in this scan | +| DeletedUSN | int | | Yes | | | | USN when the resource was deleted (NULL = still present) | + +**Primary Key:** `PK_SA_FSAA_Resources` — clustered on `(HOST, ID)` +**Foreign Keys:** +- `FK_SA_FSAA_Resources_HOST` — `(HOST) → SA_FSAA_Hosts(ID) ON DELETE CASCADE` +- `FK_SA_FSAA_Resources_ParentResourceID` — `(HOST, ParentResourceID) → SA_FSAA_Resources(HOST, ID)` +- `FK_SA_FSAA_Resources_OwnerID` — `(HOST, OwnerID) → SA_FSAA_Trustees(HOST, ID)` + +**Indexes:** +- `SA_FSAA_Resources_Enum_IDX` — nonclustered on `(HOST, ParentResourceID)` INCLUDE `(ID, ResourceType, DeletedUSN)` +- `SA_FSAA_Resources_RightsProxyID_IDX` — nonclustered on `(HOST, RightsProxyID)` INCLUDE `(ID, GatesProxyID, DeletedUSN, ResourceType)` +- `SA_FSAA_Resources_GatesProxyID_IDX` — nonclustered on `(HOST, GatesProxyID)` INCLUDE `(ID)` +- `SA_FSAA_Resources_USN_IDX` — nonclustered on `(HOST, USN)` INCLUDE `(ID)` +- `SA_FSAA_Resources_ParentResourceID_Name_IDX` — nonclustered on `(HOST, ParentResourceID, Name)` + +### SA_FSAA_UnixRights {#sa_fsaa_unixrights} + +POSIX permission triplet (`Mask`, owner, group) for Unix/NFS resources. One row per resource that has Unix rights. The `Mask` column stores the standard POSIX mode bits. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| ResourceID | bigint | | No | PK | FK → SA_FSAA_Resources.ID | | Resource these rights apply to | +| OwnerID | int | | No | | FK → SA_FSAA_Trustees.ID | | POSIX owner trustee | +| GroupID | int | | No | | FK → SA_FSAA_Trustees.ID | | POSIX group trustee | +| Mask | int | | No | | | | POSIX mode mask | +| USN | int | | No | | | | Update Sequence Number | + +**Primary Key:** `PK_SA_FSAA_UnixRights` — clustered on `(HOST, ResourceID)` +**Foreign Keys:** +- `FK_SA_FSAA_UnixRights_ResourceID` — `(HOST, ResourceID) → SA_FSAA_Resources(HOST, ID) ON DELETE CASCADE` +- `FK_SA_FSAA_UnixRights_OwnerID` — `(HOST, OwnerID) → SA_FSAA_Trustees(HOST, ID)` +- `FK_SA_FSAA_UnixRights_GroupID` — `(HOST, GroupID) → SA_FSAA_Trustees(HOST, ID)` + +**Indexes:** None beyond the clustered PK + +### SA_FSAA_Gates {#sa_fsaa_gates} + +A "gate" is the entry point through which clients reach a resource: an SMB share, an NFS export, an NFS export policy, or an Azure Files share. Gates have their own ACLs (share permissions) separate from resource ACLs. A gate references the underlying `ShareID` and the `FolderID` it grants access to. NFS share-level ACLs are modeled as a separate "policy" gate referenced by the `PolicyID` self-FK. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | FK → SA_FSAA_Hosts.ID | | Host partition | +| ID | int | | No | PK | | | Per-host gate ID | +| ShareID | bigint | | Yes | | FK → SA_FSAA_Resources.ID | | Resource that represents the share root | +| FolderID | bigint | | Yes | | FK → SA_FSAA_Resources.ID | | Folder the gate grants access to | +| PolicyID | int | | Yes | | FK → SA_FSAA_Gates.ID | | Self-FK — points at the export-policy gate when this is an NFS export | +| DisplayName | nvarchar | 256 | No | | | | Share name (e.g. `Public$`) | +| Path | nvarchar | 512 | Yes | | | | Local path of the share (e.g. `C:\Shares\Public`) | +| NestedLevel | int | | Yes | | | | Depth from the host root | +| GateType | int | | No | | | `0` | See [GateType enumeration](../enumeration/overview.md#gatetype) | +| USN | int | | No | | | `-1` | Update Sequence Number | +| DeletedUSN | int | | Yes | | | | USN at deletion (NULL = still present) | + +**Primary Key:** `PK_SA_FSAA_Gates` — clustered on `(HOST, ID)` +**Foreign Keys:** +- `FK_SA_FSAA_Gates_HOST` — `(HOST) → SA_FSAA_Hosts(ID) ON DELETE CASCADE` +- `FK_SA_FSAA_Gates_ShareID` — `(HOST, ShareID) → SA_FSAA_Resources(HOST, ID)` +- `FK_SA_FSAA_Gates_FolderID` — `(HOST, FolderID) → SA_FSAA_Resources(HOST, ID)` +- `FK_SA_FSAA_Gates_PolicyID` — `(HOST, PolicyID) → SA_FSAA_Gates(HOST, ID)` (self-FK for NFS export policies) + +**Indexes:** None beyond the clustered PK + +### SA_FSAA_GatesProxy {#sa_fsaa_gatesproxy} + +Many-to-many bridge from a resource to gates. A resource may be reachable through multiple shares (or no share at all). The proxy `ID` is denormalized onto `SA_FSAA_Resources.GatesProxyID`. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| ID | bigint | | No | PK | | | Proxy ID — referenced by `Resources.GatesProxyID` | +| GateID | int | | No | PK | FK → SA_FSAA_Gates.ID | | Gate that grants reach to this resource | + +**Primary Key:** `PK_SA_FSAA_GatesProxy` — clustered on `(HOST, ID, GateID)` +**Foreign Keys:** `FK_SA_FSAA_GatesProxy_GateID` — `(HOST, GateID) → SA_FSAA_Gates(HOST, ID) ON DELETE CASCADE` +**Indexes:** `SA_FSAA_GatesProxy_GateID_IDX` — nonclustered on `(HOST, GateID)` INCLUDE `(ID)` + +### SA_FSAA_Policies {#sa_fsaa_policies} + +Local Security Authority (LSA) policies attached to a host's policy gates (e.g. *Logon as a service*, *Allow log on locally*). Used by the `SA_FSAA_GetPolicyMembership` UDF to expand pseudo-trustees such as `NT AUTHORITY\INTERACTIVE` and `NT AUTHORITY\SERVICE` into underlying user accounts. `PolicyID` is a FK into `SA_FSAA_Gates` because policies are modelled as a special gate type. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| PolicyID | int | | No | PK | FK → SA_FSAA_Gates.ID | | Policy gate (1 = INTERACTIVE, 3 = BATCH, 4 = SERVICE, 5 = TERMINAL SERVER USER) | +| TrusteeID | int | | No | PK | FK → SA_FSAA_Trustees.ID | | Trustee assigned to the policy | +| Allow | smallint | | No | | | | Allow flag (1 = granted, 0 = denied) | + +**Primary Key:** `PK_SA_FSAA_Policies` — clustered on `(HOST, PolicyID, TrusteeID)` +**Foreign Keys:** +- `FK_SA_FSAA_Policies_PolicyID` — `(HOST, PolicyID) → SA_FSAA_Gates(HOST, ID) ON DELETE CASCADE` +- `FK_SA_FSAA_Policies_TrusteeID` — `(HOST, TrusteeID) → SA_FSAA_Trustees(HOST, ID)` + +**Indexes:** None beyond the clustered PK + +### SA_FSAA_Exceptions {#sa_fsaa_exceptions} + +One row per detected access-control anomaly (e.g. *Open Access*, *Broken Inheritance*, *Direct User Permissions*). The kind of anomaly is identified by `ExceptionType` joining `SA_FSAA_ExceptionTypes`. Either `ResourceID`, `GateID`, `TrusteeID`, or `SourceTrusteeID` may be NULL depending on the exception class. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | FK → SA_FSAA_Hosts.ID | | Host partition | +| ID | int | | No | PK | | | Per-host exception ID | +| ExceptionType | int | | No | | FK → SA_FSAA_ExceptionTypes.ExceptionType | | Class of exception | +| GateID | int | | Yes | | FK → SA_FSAA_Gates.ID | | Gate involved (if any) | +| ResourceID | bigint | | Yes | | FK → SA_FSAA_Resources.ID | | Resource involved (if any) | +| TrusteeID | int | | Yes | | FK → SA_FSAA_Trustees.ID | | Subject trustee (if any) | +| SourceTrusteeID | int | | Yes | | FK → SA_FSAA_Trustees.ID | | Source trustee — for SID-History exceptions, the historical SID's owner | + +**Primary Key:** `PK_SA_FSAA_Exceptions` — clustered on `(HOST, ID)` +**Foreign Keys:** +- `FK_SA_FSAA_Exceptions_HOST` — `(HOST) → SA_FSAA_Hosts(ID)` +- `FK_SA_FSAA_Exceptions_GateID` — `(HOST, GateID) → SA_FSAA_Gates(HOST, ID) ON DELETE CASCADE` +- `FK_SA_FSAA_Exceptions_ResourceID` — `(HOST, ResourceID) → SA_FSAA_Resources(HOST, ID)` +- `FK_SA_FSAA_Exceptions_TrusteeID` — `(HOST, TrusteeID) → SA_FSAA_Trustees(HOST, ID)` +- `FK_SA_FSAA_Exceptions_SourceTrusteeID` — `(HOST, SourceTrusteeID) → SA_FSAA_Trustees(HOST, ID)` + +**Indexes:** `SA_FSAA_Exceptions_Resource_IDX` — nonclustered on `(HOST, ResourceID)` INCLUDE `(ExceptionType, GateID)` + +### SA_FSAA_ExceptionTypes {#sa_fsaa_exceptiontypes} + +Per-host catalog of every exception class FSAA can detect. `ParentType` allows hierarchical grouping of related exceptions. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | FK → SA_FSAA_Hosts.ID | | Host partition | +| ExceptionType | int | | No | PK | | | Type code (referenced by `Exceptions.ExceptionType`) | +| GUID | varchar | 38 | No | | | | Stable GUID identifying this exception kind | +| USN | int | | No | | | | Update Sequence Number | +| Name | varchar | 128 | No | | | | Short name (e.g. `OpenAccess`) | +| Description | varchar | 256 | No | | | | Human-readable description | +| Count | int | | No | | | | Cached count of `SA_FSAA_Exceptions` rows of this type | +| ParentType | int | | Yes | | | | Optional parent exception type (self-reference within the host) | + +**Primary Key:** `PK_SA_FSAA_ExceptionTypes` — clustered on `(HOST, ExceptionType)` +**Foreign Keys:** `FK_SA_FSAA_ExceptionTypes_HOST` — `(HOST) → SA_FSAA_Hosts(ID) ON DELETE CASCADE` +**Indexes:** None beyond the clustered PK + +### SA_FSAA_ProbableOwners {#sa_fsaa_probableowners} + +Probable-owner heuristic results — one row per `(resource, candidate-owner)` pair, scored by file count and aggregated size of files the candidate owns within the resource subtree. Populated by the *Probable Owner* analysis job. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| ResourceID | bigint | | No | PK | FK → SA_FSAA_Resources.ID | | Resource (folder/share) being scored | +| OwnerID | int | | No | PK | FK → SA_FSAA_Trustees.ID | | Candidate owner | +| FileSize | bigint | | Yes | | | | Total bytes owned by this candidate within the subtree | +| FileCount | int | | Yes | | | | Number of files owned by this candidate within the subtree | + +**Primary Key:** `PK_SA_FSAA_ProbableOwners` — clustered on `(HOST, ResourceID, OwnerID)` +**Foreign Keys:** +- `FK_SA_FSAA_ProbableOwners_HOST` — `(HOST) → SA_FSAA_Hosts(ID) ON DELETE CASCADE` +- `FK_SA_FSAA_ProbableOwners_ResourceID` — `(HOST, ResourceID) → SA_FSAA_Resources(HOST, ID)` +- `FK_SA_FSAA_ProbableOwners_OwnerID` — `(HOST, OwnerID) → SA_FSAA_Trustees(HOST, ID)` + +**Indexes:** None beyond the clustered PK + +### SA_FSAA_FileSizes {#sa_fsaa_filesizes} + +Aggregated size and count of all files within each resource subtree. Populated by the bulk-import pipeline when the *Sizing* option is enabled. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| ResourceID | bigint | | No | PK | FK → SA_FSAA_Resources.ID | | Resource (folder/share) | +| FileSize | bigint | | Yes | | | | Total file bytes within the subtree | +| FileCount | int | | Yes | | | | Total number of files within the subtree | + +**Primary Key:** `PK_SA_FSAA_FileSizes` — clustered on `(HOST, ResourceID)` +**Foreign Keys:** `FK_SA_FSAA_FileSizes_ResourceID` — `(HOST, ResourceID) → SA_FSAA_Resources(HOST, ID) ON DELETE CASCADE` +**Indexes:** None beyond the clustered PK + +### SA_FSAA_FileTypes {#sa_fsaa_filetypes} + +Per-extension breakdown of files within each resource subtree. One row per `(resource, extension)`. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| ResourceID | bigint | | No | PK | FK → SA_FSAA_Resources.ID | | Resource (folder/share) | +| Extension | nvarchar | 255 | No | PK | | | File extension (e.g. `.docx`) | +| FileSize | bigint | | Yes | | | | Total bytes of files with this extension | +| FileCount | int | | Yes | | | | Number of files with this extension | + +**Primary Key:** `PK_SA_FSAA_FileTypes` — clustered on `(HOST, ResourceID, Extension)` +**Foreign Keys:** `FK_SA_FSAA_FileTypes_ResourceID` — `(HOST, ResourceID) → SA_FSAA_Resources(HOST, ID) ON DELETE CASCADE` +**Indexes:** None beyond the clustered PK + +### SA_FSAA_FileAges {#sa_fsaa_fileages} + +Histogram of file age buckets within each resource subtree. The eleven `FileCount0`–`FileCount10` columns hold counts in successively older buckets; bucket boundaries are determined at scan configuration time. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| ResourceID | bigint | | No | PK | FK → SA_FSAA_Resources.ID | | Resource (folder/share) | +| LastModified | datetime | | Yes | | | | Most recent file modification within the subtree | +| FileCount0 | int | | Yes | | | | Files in age bucket 0 (newest) | +| FileCount1 | int | | Yes | | | | Files in age bucket 1 | +| FileCount2 | int | | Yes | | | | Files in age bucket 2 | +| FileCount3 | int | | Yes | | | | Files in age bucket 3 | +| FileCount4 | int | | Yes | | | | Files in age bucket 4 | +| FileCount5 | int | | Yes | | | | Files in age bucket 5 | +| FileCount6 | int | | Yes | | | | Files in age bucket 6 | +| FileCount7 | int | | Yes | | | | Files in age bucket 7 | +| FileCount8 | int | | Yes | | | | Files in age bucket 8 | +| FileCount9 | int | | Yes | | | | Files in age bucket 9 | +| FileCount10 | int | | Yes | | | | Files in age bucket 10 (oldest) | + +**Primary Key:** `PK_SA_FSAA_FileAges` — clustered on `(HOST, ResourceID)` +**Foreign Keys:** `FK_SA_FSAA_FileAges_ResourceID` — `(HOST, ResourceID) → SA_FSAA_Resources(HOST, ID) ON DELETE CASCADE` +**Indexes:** None beyond the clustered PK + +### SA_FSAA_FileTags {#sa_fsaa_filetags} + +Aggregated file count and size per `(resource, tag-set)`. Populated when AIP or sensitive-data tags are collected. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| ResourceID | bigint | | No | PK | FK → SA_FSAA_Resources.ID | | Resource (folder/share) | +| TagProxyID | int | | No | PK | FK → SA_FSAA_TagKeys.TagProxyID | | Tag set | +| FileSize | bigint | | No | | | | Total bytes of files with this tag set | +| FileCount | int | | No | | | | Number of files with this tag set | + +**Primary Key:** `PK_SA_FSAA_FileTags` — clustered on `(HOST, ResourceID, TagProxyID)` +**Foreign Keys:** +- `FK_SA_FSAA_FileTags_ResourceID` — `(HOST, ResourceID) → SA_FSAA_Resources(HOST, ID) ON DELETE CASCADE` +- `FK_SA_FSAA_FileTags_TagProxyID` — `(HOST, TagProxyID) → SA_FSAA_TagKeys(HOST, TagProxyID)` + +**Indexes:** None beyond the clustered PK + +### SA_FSAA_ScanHistory {#sa_fsaa_scanhistory} + +Append-only audit log of every scan run, including the FSAA configuration XML used. Useful for forensic and configuration-tracking purposes. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| ConsoleHost | nvarchar | 64 | Yes | | | | NAA console that initiated the scan | +| ScanHost | nvarchar | 64 | Yes | | | | Host machine that performed the scan | +| ScanType | nvarchar | 64 | Yes | | | | Scan type (Access / Activity / DLP) | +| JobGUID | varchar | 38 | Yes | | | | Job correlation GUID | +| RunTime | datetime2 | | Yes | | | | When the scan ran | +| FSAAConfigXml | xml | | Yes | | | | Snapshot of the FSAA XML configuration | + +**Primary Key:** None +**Foreign Keys:** None +**Indexes:** None + +### SA_FSAA_AzureFilesShares {#sa_fsaa_azurefilesshares} + +Catalog of Azure Files shares discovered on a host. Each share is linked back to a `SA_FSAA_Resources` row (the share root) and a `SA_FSAA_Gates` row (the share gate). `StorageAccount` carries the FQDN of the storage account. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | FK → SA_FSAA_Hosts.ID | | Host partition | +| ID | int | | No | PK | | | Per-host Azure share ID | +| ResourceID | bigint | | No | | FK → SA_FSAA_Resources.ID | | Share-root resource | +| GateID | int | | No | | FK → SA_FSAA_Gates.ID | | Share gate | +| Name | nvarchar | 2000 | Yes | | | | Share name | +| StorageAccount | varchar | 256 | Yes | | | | Storage-account FQDN (e.g. `acct.file.core.windows.net`) | + +**Primary Key:** `PK_SA_FSAA_AzureFilesShares` — clustered on `(HOST, ID)` +**Foreign Keys:** +- `FK_SA_FSAA_AzureFilesShares_HOST` — `(HOST) → SA_FSAA_Hosts(ID) ON DELETE CASCADE` +- `FK_SA_FSAA_AzureFilesShares_ResourceID` — `(HOST, ResourceID) → SA_FSAA_Resources(HOST, ID)` +- `FK_SA_FSAA_AzureFilesShares_GateID` — `(HOST, GateID) → SA_FSAA_Gates(HOST, ID)` + +**Indexes:** None beyond the clustered PK + +### SA_FSAA_AzureFilesShareProperties {#sa_fsaa_azurefilesshareproperties} + +Azure-Files-specific metadata that doesn't fit the generic resource model: tier, lease, retention, quota, and soft-delete state. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| AzureShareID | int | | No | PK | FK → SA_FSAA_AzureFilesShares.ID | | Azure share | +| AccessTier | varchar | 50 | Yes | | | | `Hot` / `Cool` / `Premium` / `TransactionOptimized` | +| AccessChangeTime | datetime2 | 7 | Yes | | | | When tier was last changed | +| AccessTierTransitionState | varchar | 50 | Yes | | | | In-progress tier transition state | +| DeletedOn | datetime2 | 7 | Yes | | | | Soft-delete timestamp (NULL if not deleted) | +| LastModified | datetime2 | 7 | Yes | | | | Last modified timestamp | +| LeaseDuration | varchar | 50 | Yes | | | | Lease duration (`Fixed` / `Infinite`) | +| LeaseStatus | varchar | 50 | Yes | | | | Lease status (`Locked` / `Unlocked`) | +| LeaseState | varchar | 50 | Yes | | | | Lease state (`Available` / `Leased` / `Expired` / `Breaking` / `Broken`) | +| EnabledProtocols | varchar | 50 | Yes | | | | Enabled protocols (`SMB`, `NFS`) | +| RemainingRetentionDays | int | | Yes | | | | Soft-delete retention days remaining | +| QuotaInGB | float | | Yes | | | | Configured share quota (GiB) | + +**Primary Key:** `PK_SA_FSAA_AzureFilesShareProperties` — clustered on `(HOST, AzureShareID)` +**Foreign Keys:** `FK_SA_FSAA_AzureFilesShareProperties_AzureShareID` — `(HOST, AzureShareID) → SA_FSAA_AzureFilesShares(HOST, ID) ON DELETE CASCADE` +**Indexes:** None beyond the clustered PK + +### SA_FSAA_AzureStorageAccounts {#sa_fsaa_azurestorageaccounts} + +Single-column lookup of every Azure Storage Account hostname known to FSAA. Used by the data-collection job to expand a configured storage account into its discoverable file shares. + +:::note +The unusual single-column shape exists because the `HOST` column name is required for NAA's dynamic host-list generation. This table carries no foreign keys and no indexes. +::: + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | nvarchar | 46 | No | | | | Storage-account FQDN (max 24 chars + `.file.core.windows.net` suffix) | + +**Primary Key:** None +**Foreign Keys:** None +**Indexes:** None + +### SA_FSAA_TrusteeMap {#sa_fsaa_trusteemap} + +Cross-module identity map. Each FSAA trustee may correspond to a distinct trustee row in the FSAC (Activity) and FSDLP (DLP) tables. This table holds those mappings so the three sub-collectors can present unified results. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| ID | int | | No | PK | FK → SA_FSAA_Trustees.ID | | FSAA trustee ID | +| AccessID | int | | Yes | | | | Corresponding ID in Access (FSAA) data — typically same as `ID` | +| ActivityID | int | | Yes | | | | Corresponding ID in Activity (FSAC) trustee table | +| DLPID | int | | Yes | | | | Corresponding ID in DLP (FSDLP) trustee table | + +**Primary Key:** `PK_SA_FSAA_TrusteeMap` — clustered on `(HOST, ID)` +**Foreign Keys:** `FK_SA_FSAA_TrusteeMap_ID` — `(HOST, ID) → SA_FSAA_Trustees(HOST, ID)` +**Indexes:** None beyond the clustered PK + +### SA_FSAA_ResourceMap {#sa_fsaa_resourcemap} + +Cross-module resource identity map. Same role as `SA_FSAA_TrusteeMap` but for resources. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| ID | bigint | | No | PK | FK → SA_FSAA_Resources.ID | | FSAA resource ID | +| AccessID | bigint | | Yes | | | | Corresponding Access (FSAA) ID | +| ActivityID | bigint | | Yes | | | | Corresponding Activity (FSAC) ID | +| DLPID | bigint | | Yes | | | | Corresponding DLP (FSDLP) ID | + +**Primary Key:** `PK_SA_FSAA_ResourceMap` — clustered on `(HOST, ID)` +**Foreign Keys:** `FK_SA_FSAA_ResourceMap_ID` — `(HOST, ID) → SA_FSAA_Resources(HOST, ID)` +**Indexes:** +- `SA_FSAA_ResourceMap_AccessID_IDX` — nonclustered on `(HOST, AccessID)` +- `SA_FSAA_ResourceMap_ActivityID_IDX` — nonclustered on `(HOST, ActivityID)` +- `SA_FSAA_ResourceMap_DLPID_IDX` — nonclustered on `(HOST, DLPID)` + +### SA_FSAA_GateMap {#sa_fsaa_gatemap} + +Cross-module gate identity map. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| ID | int | | No | PK | FK → SA_FSAA_Gates.ID | | FSAA gate ID | +| AccessID | int | | Yes | | | | Corresponding Access ID | +| ActivityID | int | | Yes | | | | Corresponding Activity ID | +| DLPID | int | | Yes | | | | Corresponding DLP ID | + +**Primary Key:** `PK_SA_FSAA_GateMap` — clustered on `(HOST, ID)` +**Foreign Keys:** `FK_SA_FSAA_GateMap_ID` — `(HOST, ID) → SA_FSAA_Gates(HOST, ID)` +**Indexes:** None beyond the clustered PK + +### SA_FSAA_ResourcesScanTypeDetails {#sa_fsaa_resourcesscantypedetails} + +Per-resource USN tracking columns split out of `SA_FSAA_Resources` in schema version 8.0. One row per resource, holding per-scan-type "last seen" / "last deleted" timestamps and USNs for Access, Activity, and DLP. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| ID | bigint | | No | PK | FK → SA_FSAA_Resources.ID | | Resource ID | +| AccessUSN | int | | Yes | | | | USN at last Access sighting | +| AccessLastSeen | datetime2 | | Yes | | | | Last time Access scan saw this resource | +| AccessLastDeleted | datetime2 | | Yes | | | | Time the resource was last marked deleted by Access | +| ActivityUSN | int | | Yes | | | | USN at last Activity sighting | +| ActivityLastSeen | datetime2 | | Yes | | | | Last time Activity scan saw this resource | +| ActivityLastDeleted | datetime2 | | Yes | | | | Time the resource was last marked deleted by Activity | +| DLPUSN | int | | Yes | | | | USN at last DLP sighting | +| DLPLastSeen | datetime2 | | Yes | | | | Last time DLP saw this resource | +| DLPLastDeleted | datetime2 | | Yes | | | | Time the resource was last marked deleted by DLP | + +**Primary Key:** `PK_SA_FSAA_ResourcesScanTypeDetails` — clustered on `(HOST, ID)` +**Foreign Keys:** `FK_SA_FSAA_ResourcesScanTypeDetails_ID` — `(HOST, ID) → SA_FSAA_Resources(HOST, ID)` +**Indexes:** None beyond the clustered PK + +## Activity Collector Tables (SA_FSAC_*) + +### SA_FSAC_ProcessNames {#sa_fsac_processnames} + +Per-host lookup of process names observed in audit events. Activity events reference process names by `ID` to avoid storing the same long path string repeatedly. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | FK → SA_FSAA_Hosts.ID | | Host partition | +| ID | int | | No | PK | | | Per-host process-name ID | +| Name | nvarchar | 255 | No | | | | Process name (e.g. `EXPLORER.EXE`) | + +**Primary Key:** `PK_SA_FSAC_ProcessNames` — clustered on `(HOST, ID)` +**Foreign Keys:** `FK_SA_FSAC_ProcessNames_HOST` — `(HOST) → SA_FSAA_Hosts(ID) ON DELETE CASCADE` +**Indexes:** None beyond the clustered PK + +### SA_FSAC_ActivityEvents {#sa_fsac_activityevents} + +The activity-event firehose. One row per audited file-system operation captured by an FSAC agent. `Operation` is a coded enumeration covering Read / Add / Update / Delete / PermissionChange / Rename. `Allow` is `1` for successful operations and `0` for denied operations. + +:::note +The `AccessTime` column type differs by environment: fresh-install DDL uses `datetime2`; the Task-15 migration recreates the table with `datetime`. Post-migration environments have `datetime`. +::: + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | FK → SA_FSAA_Hosts.ID | | Host partition | +| ID | bigint | | No | PK | | | Per-host event ID | +| AccessTime | datetime / datetime2 | | No | | | | Time the operation occurred | +| PathID | bigint | | No | | FK → SA_FSAA_Resources.ID | | Resource (file or folder) the operation acted on | +| TrusteeID | int | | No | | FK → SA_FSAA_Trustees.ID | | The user / principal that performed the operation | +| ProcessID | int | | Yes | | FK → SA_FSAC_ProcessNames.ID | | Process executing the operation (NULL if unknown) | +| Operation | tinyint | | No | | | | `0`=Read, `1`=Add, `2`=Update, `3`=Delete, `4`=PermissionChange, `5`=Rename | +| Allow | bit | | No | | | `1` | `1` = operation allowed, `0` = operation denied | +| USN | int | | No | | | | Update Sequence Number | + +**Primary Key:** `PK_SA_FSAC_ActivityEvents` — clustered on `(HOST, ID)` +**Foreign Keys:** +- `FK_SA_FSAC_ActivityEvents_HOST` — `(HOST) → SA_FSAA_Hosts(ID) ON DELETE CASCADE` +- `FK_SA_FSAC_ActivityEvents_PathID` — `(HOST, PathID) → SA_FSAA_Resources(HOST, ID)` +- `FK_SA_FSAC_ActivityEvents_ProcessID` — `(HOST, ProcessID) → SA_FSAC_ProcessNames(HOST, ID)` +- `FK_SA_FSAC_ActivityEvents_TrusteeID` — `(HOST, TrusteeID) → SA_FSAA_Trustees(HOST, ID)` + +**Indexes:** +- `SA_FSAC_ActivityEvents_PathID_IDX` — nonclustered on `(HOST, PathID)` INCLUDE `(ID, AccessTime, TrusteeID, Operation, Allow)` +- `SA_FSAC_ActivityEvents_TrusteeID_IDX` — nonclustered on `(TrusteeID, AccessTime)` INCLUDE `(PathID, ProcessID, Operation, Allow)` + +### SA_FSAC_PermissionChanges {#sa_fsac_permissionchanges} + +Detail rows for activity events where `Operation = 4` (PermissionChange). Each event may have multiple change rows — one per ACE that was added, removed, or modified. `AccessRights` is the bitmask before the change; `NewAccessRights` is the bitmask after (NULL on removal). + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | FK → SA_FSAA_Hosts.ID | | Host partition | +| ActivityID | bigint | | No | PK | FK → SA_FSAC_ActivityEvents.ID | | Owning activity event | +| ChangeID | smallint | | No | PK | | | Per-event change index | +| AclType | tinyint | | No | | | | ACL type (DACL / SACL distinction) | +| TrusteeID | int | | No | | FK → SA_FSAA_Trustees.ID | | Trustee whose ACE changed | +| ChangeType | tinyint | | No | | | | Change kind: added / removed / modified | +| AceType | tinyint | | No | | | | ACE type (Allow / Deny) | +| InheritanceFlags | tinyint | | No | | | | NTFS inheritance flags | +| AceFlags | tinyint | | No | | | | NTFS ACE flags | +| AccessRights | bigint | | No | | | | Pre-change Windows access mask | +| NewAccessRights | bigint | | Yes | | | | Post-change access mask (NULL when ACE was removed) | + +**Primary Key:** `PK_SA_FSAC_PermissionChanges` — clustered on `(HOST, ActivityID, ChangeID)` +**Foreign Keys:** +- `FK_SA_FSAC_PermissionChanges_HOST` — `(HOST) → SA_FSAA_Hosts(ID)` +- `FK_SA_FSAC_PermissionChanges_ActivityID` — `(HOST, ActivityID) → SA_FSAC_ActivityEvents(HOST, ID)` +- `FK_SA_FSAC_PermissionChanges_TrusteeID` — `(HOST, TrusteeID) → SA_FSAA_Trustees(HOST, ID)` + +**Indexes:** None beyond the clustered PK + +### SA_FSAC_OwnerChanges {#sa_fsac_ownerchanges} + +Detail rows for activity events that changed a resource's owner (Take Ownership / chown). One row per qualifying activity event. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | FK → SA_FSAA_Hosts.ID | | Host partition | +| ActivityID | bigint | | No | PK | FK → SA_FSAC_ActivityEvents.ID | | Owning activity event | +| PreviousOwnerID | int | | No | | FK → SA_FSAA_Trustees.ID | | Owner before the change | +| NewOwnerID | int | | No | | FK → SA_FSAA_Trustees.ID | | Owner after the change | + +**Primary Key:** `PK_SA_FSAC_OwnerChanges` — clustered on `(HOST, ActivityID)` +**Foreign Keys:** +- `FK_SA_FSAC_OwnerChanges_HOST` — `(HOST) → SA_FSAA_Hosts(ID)` +- `FK_SA_FSAC_OwnerChanges_ActivityID` — `(HOST, ActivityID) → SA_FSAC_ActivityEvents(HOST, ID)` +- `FK_SA_FSAC_OwnerChanges_PreviousOwnerID` — `(HOST, PreviousOwnerID) → SA_FSAA_Trustees(HOST, ID)` +- `FK_SA_FSAC_OwnerChanges_NewOwnerID` — `(HOST, NewOwnerID) → SA_FSAA_Trustees(HOST, ID)` + +**Indexes:** None beyond the clustered PK + +### SA_FSAC_DailyActivity {#sa_fsac_dailyactivity} + +Daily aggregation of activity-event counts, partitioned by `(host, date, folder, trustee, operation, allow)`. Feeds the daily-activity views and the *Most Active Users* / *Most Active Servers* reports. + +:::note +The PK was added by a migration block; fresh CREATE TABLE has no PK — the migration adds it if absent. +::: + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | FK → SA_FSAA_Hosts.ID | | Host partition | +| ActivityDate | date | | No | PK | | | Date the activity occurred | +| FolderID | bigint | | No | PK | FK → SA_FSAA_Resources.ID | | Containing folder | +| TrusteeID | int | | No | PK | FK → SA_FSAA_Trustees.ID | | Acting trustee | +| Operation | tinyint | | No | PK | | | Operation code (0–5) | +| Allow | bit | | No | PK | | `1` | Allow / Deny flag | +| Count | int | | No | | | | Number of operations | + +**Primary Key:** `PK_SA_FSAC_DailyActivity` — clustered on `(HOST, FolderID, ActivityDate, TrusteeID, Operation, Allow)` +**Foreign Keys:** +- `FK_SA_FSAC_DailyActivity_HOST` — `(HOST) → SA_FSAA_Hosts(ID) ON DELETE CASCADE` +- `FK_SA_FSAC_DailyActivity_FolderID` — `(HOST, FolderID) → SA_FSAA_Resources(HOST, ID)` +- `FK_SA_FSAC_DailyActivity_TrusteeID` — `(HOST, TrusteeID) → SA_FSAA_Trustees(HOST, ID)` + +**Indexes:** None beyond the clustered PK + +### SA_FSAC_RenameTargets {#sa_fsac_renametargets} + +Detail rows for `Operation = 5` (Rename) activity events: stores the *target* path-ID of the rename. The activity event itself records the *source* path; this table records the destination. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | FK → SA_FSAA_Hosts.ID | | Host partition | +| ActivityID | bigint | | No | PK | FK → SA_FSAC_ActivityEvents.ID | | Owning rename event | +| TargetPathID | bigint | | No | | FK → SA_FSAA_Resources.ID | | Resource the source was renamed to | + +**Primary Key:** `PK_SA_FSAC_RenameTargets` — clustered on `(HOST, ActivityID)` +**Foreign Keys:** +- `FK_SA_FSAC_RenameTargets_HOST` — `(HOST) → SA_FSAA_Hosts(ID) ON DELETE CASCADE` +- `FK_SA_FSAC_RenameTargets_ActivityID` — `(HOST, ActivityID) → SA_FSAC_ActivityEvents(HOST, ID)` +- `FK_SA_FSAC_RenameTargets_TargetPathID` — `(HOST, TargetPathID) → SA_FSAA_Resources(HOST, ID)` + +**Indexes:** None beyond the clustered PK + +### SA_FSAC_ExceptionTypes {#sa_fsac_exceptiontypes} + +Catalog of activity-exception classes (e.g. *Unusual hourly activity*, *Mass deletion*, *Ransomware artifact*). One row per `(host, exception type)`. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| ExceptionType | int | | No | PK | | | Exception type code | +| Name | varchar | 128 | No | | | | Short name | +| Description | varchar | 256 | No | | | | Human-readable description | +| Count | int | | No | | | | Cached count of `SA_FSAC_Exceptions` rows of this type | +| ParentType | int | | Yes | | | | Optional parent exception type for hierarchical grouping | + +**Primary Key:** `PK_SA_FSAC_ExceptionTypes` — clustered on `(HOST, ExceptionType)` +**Foreign Keys:** None +**Indexes:** None beyond the clustered PK + +### SA_FSAC_Exceptions {#sa_fsac_exceptions} + +One row per detected activity anomaly. The `Value` / `Average` / `StandardDeviations` columns capture the statistical model output that triggered the exception. + +:::note +`ExceptionType` is a logical (un-enforced) reference to `SA_FSAC_ExceptionTypes.ExceptionType` — no FK constraint is created. +::: + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| ID | int | | No | PK | | | Per-host exception ID | +| ExceptionType | int | | No | | | | Class of exception (logical reference to `SA_FSAC_ExceptionTypes`) | +| ActivityDate | date | | No | | | | Date the anomaly occurred | +| ActivityHour | tinyint | | Yes | | | | Hour-of-day (0–23) for hourly-bucketed anomalies | +| GateID | int | | No | | | | Gate (share) where the anomaly was observed | +| TrusteeID | int | | Yes | | | | User involved (if applicable) | +| ResourceID | bigint | | Yes | | | | Resource involved (if applicable) | +| Value | int | | Yes | | | | Observed value (e.g. operation count) | +| Average | float | | Yes | | | | Baseline average for comparison | +| StandardDeviations | float | | Yes | | | | How many σ the observed value is from the average | + +**Primary Key:** `PK_SA_FSAC_Exceptions` — clustered on `(HOST, ID)` +**Foreign Keys:** None +**Indexes:** `SA_FSAC_Exceptions_ResourceID_IDX` — nonclustered on `(HOST, ResourceID)` INCLUDE `(GateID)` + +### SA_FSAC_UserExceptionTypes {#sa_fsac_userexceptiontypes} + +User-centric variant of `SA_FSAC_ExceptionTypes` — partitioned by user `SID` instead of by host. Used when an exception is associated with a particular user across multiple hosts. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| SID | varchar | 184 | No | PK | | | User SID | +| ExceptionType | int | | No | PK | | | Exception type code | +| Name | varchar | 128 | No | | | | Short name | +| Description | varchar | 256 | No | | | | Description | +| Count | int | | No | | | | Cached count | +| ParentType | int | | Yes | | | | Optional parent exception type | + +**Primary Key:** `PK_SA_FSAC_UserExceptionTypes` — clustered on `(SID, ExceptionType)` +**Foreign Keys:** None +**Indexes:** None beyond the clustered PK + +### SA_FSAC_UserExceptions {#sa_fsac_userexceptions} + +One row per detected per-user activity anomaly (e.g. unusual login pattern attributed to a specific SID). + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| SID | varchar | 184 | No | | | | User SID | +| ID | int | | No | PK | | | Surrogate exception ID | +| ExceptionType | int | | No | | | | Exception type | +| ActivityDate | date | | No | | | | Date the anomaly occurred | +| ActivityStartTime | tinyint | | Yes | | | | Start hour of the activity window (0–23) | +| ActivityPeriod | tinyint | | Yes | | | | Length of the activity window in hours | +| Value | int | | Yes | | | | Observed value | +| Average | float | | Yes | | | | Baseline average | +| StandardDeviations | float | | Yes | | | | σ from baseline | + +**Primary Key:** `PK_SA_FSAC_UserExceptions` — clustered on `(ID)` +**Foreign Keys:** None +**Indexes:** None beyond the clustered PK + +## Sensitive Data Tables (SA_FSDLP_*) + +### SA_FSDLP_ImportHistory {#sa_fsdlp_importhistory} + +Append-only history of DLP scan imports per host. One row per imported scan run. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | FK → SA_FSAA_Hosts.ID | | Host partition | +| GUID | varchar | 38 | No | | | | Scan correlation GUID | +| USN | int | | No | PK | | | USN at import time | + +**Primary Key:** `PK_SA_FSDLP_ImportHistory` — clustered on `(HOST, USN)` +**Foreign Keys:** `FK_SA_FSDLP_ImportHistory_HOST` — `(HOST) → SA_FSAA_Hosts(ID) ON DELETE CASCADE` +**Indexes:** None beyond the clustered PK + +### SA_FSDLP_Criteria {#sa_fsdlp_criteria} + +Per-host catalog of the DLP criteria (patterns / classifiers) that produced matches. The `pattern_guid` is the global identifier linking back to centrally managed criteria definitions. `Risk` is a numeric severity score. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | FK → SA_FSAA_Hosts.ID | | Host partition | +| ID | int | | No | PK | | | Per-host criterion ID | +| Name | nvarchar | 256 | No | | | | Criterion name (e.g. "US Social Security Number") | +| Risk | int | | No | | | `0` | Risk score | +| pattern_guid | uniqueidentifier | | Yes | | | | Global criterion GUID | + +**Primary Key:** `PK_SA_FSDLP_Criteria` — clustered on `(HOST, ID)` +**Foreign Keys:** `FK_SA_FSDLP_Criteria_HOST` — `(HOST) → SA_FSAA_Hosts(ID) ON DELETE CASCADE` +**Indexes:** None beyond the clustered PK + +### SA_FSDLP_Matches {#sa_fsdlp_matches} + +One row per `(file, criterion)` pair where the criterion produced at least one hit. `MatchCount` is the total number of hits. `DataSource` is a bitmask: `1` = Content, `2` = Metadata, `4` = Filename; combinations are summed (e.g. `5` = Content + Filename). + +:::note +`FileId` is a logical (un-enforced) reference to `SA_FSAA_Resources.ID`. The DLP collector populates `FileId` to match the FSAA resource ID but no SQL FK constraint is created, so DLP imports can run independently of structural scans. +::: + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| FileId | bigint | | No | PK | | | Resource ID of the matched file (logical FK to `SA_FSAA_Resources.ID`) | +| CriteriaId | int | | No | PK | FK → SA_FSDLP_Criteria.ID | | Criterion that matched | +| MatchCount | int | | Yes | | | | Number of hits within this file for this criterion | +| DataSource | int | | No | | | `0` | Bitmask: 1=Content, 2=Metadata, 4=Filename | + +**Primary Key:** `PK_SA_FSDLP_Matches` — clustered on `(HOST, FileId, CriteriaId)` +**Foreign Keys:** `FK_SA_FSDLP_Matches_CriteriaId` — `(HOST, CriteriaId) → SA_FSDLP_Criteria(HOST, ID) ON DELETE CASCADE` +**Indexes:** None beyond the clustered PK + +### SA_FSDLP_MatchHits {#sa_fsdlp_matchhits} + +Per-hit detail rows. For every match in `SA_FSDLP_Matches`, this table holds the prefix/data/suffix excerpt around each hit, plus a confidence score. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| FileId | bigint | | No | PK | | | Resource ID of the matched file | +| CriteriaId | int | | No | PK | | | Criterion that produced the hit | +| ID | bigint | | No | PK | | | Per-`(File, Criterion)` hit ID | +| SubFileName | nvarchar | 1024 | Yes | | | | Sub-file name (for archives such as ZIP / RAR) | +| MatchPrefix | nvarchar | 1024 | Yes | | | | Text immediately before the matched data | +| MatchData | nvarchar | 1024 | Yes | | | | The matched data itself | +| MatchSuffix | nvarchar | 1024 | Yes | | | | Text immediately after the matched data | +| Confidence | int | | No | | | `0` | Confidence score (0–100) | +| DataSource | int | | No | | | `0` | Where the hit was found (see `SA_FSDLP_Matches.DataSource`) | + +**Primary Key:** `PK_SA_FSDLP_MatchHits` — clustered on `(HOST, FileId, CriteriaId, ID)` +**Foreign Keys:** `FK_SA_FSDLP_MatchHits_Match` — `(HOST, FileId, CriteriaId) → SA_FSDLP_Matches(HOST, FileId, CriteriaId) ON DELETE CASCADE` +**Indexes:** None beyond the clustered PK + +### SA_FSDLP_MatchHits_SubjectProfile {#sa_fsdlp_matchhits_subjectprofile} + +Links a DLP match hit to the subject-profile system, identifying which person or entity the hit is about. Populated when subject-profile correlation is enabled. + +:::note +The `SA_SubjectProfile_*` tables referenced by this table's foreign keys are owned by the central Subject Profile module and are documented separately. +::: + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| HOST | int | | No | PK | | | Host partition | +| FileId | bigint | | No | PK | | | Resource ID of the matched file | +| CriteriaId | int | | No | PK | | | Criterion that produced the hit | +| ID | bigint | | No | PK | FK → SA_FSDLP_MatchHits.ID | | Hit ID | +| SourceId | int | | No | FK → SA_SubjectProfile_Sources.Id | | | Subject-profile source | +| IdentityId | bigint | | No | FK → SA_SubjectProfile_Identities.Id | | | Resolved identity | +| AttributeId | int | | No | | | | Attribute on the identity that the hit aligns with | +| Order | int | | No | | | | Position within multi-valued attributes | + +**Primary Key:** `PK_SA_FSDLP_MatchHits_SubjectProfile` — clustered on `(HOST, FileId, CriteriaId, ID)` +**Foreign Keys:** +- `FK_SA_FSDLP_MatchHits_SubjectProfile` — `(HOST, FileId, CriteriaId, ID) → SA_FSDLP_MatchHits(HOST, FileId, CriteriaId, ID) ON DELETE CASCADE` +- `FK_SA_FSDLP_MatchHits_SubjectProfile_Source` — `(SourceId) → SA_SubjectProfile_Sources(Id)` +- `FK_SA_FSDLP_MatchHits_SubjectProfile_Identity` — `(IdentityId) → SA_SubjectProfile_Identities(Id)` +- `FK_SA_FSDLP_MatchHits_SubjectProfile_Attribute` — `(IdentityId, AttributeId, Order) → SA_SubjectProfile_AttributeValues(IdentityId, AttributeId, Order) ON DELETE CASCADE` + +**Indexes:** None beyond the clustered PK + +## DFS Namespace Tables (SA_FSDFS_*) + +### SA_FSDFS_Namespaces {#sa_fsdfs_namespaces} + +One row per discovered DFS namespace (e.g. `\\contoso.com\public`). Each namespace anchors zero or more DFS links. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| ID | int | | No | PK | | IDENTITY(1,1) | Surrogate namespace ID | +| HOST | int | | No | | | | Host that owns the namespace record | +| Name | nvarchar | 450 | No | | | | DFS namespace name | +| RootHostID | int | | Yes | | FK → SA_FSAA_Hosts.ID | | The FSAA host that hosts the namespace root | +| RootGateID | int | | Yes | | | | The gate (share) that backs the namespace root | +| Host | int | | Yes | | | | Alternate nullable host column added by schema migration | + +**Primary Key:** `PK_SA_FSDFS_Namespaces` — clustered on `(ID)` +**Foreign Keys:** +- `FK_SA_FSDFS_Namespaces_Hosts` — `(RootHostID) → SA_FSAA_Hosts(ID) ON DELETE CASCADE` +- `FK_SA_FSDFS_Namespaces_GateID` — `(RootHostID, RootGateID) → SA_FSAA_Gates(HOST, ID)` + +**Indexes:** None beyond the clustered PK + +### SA_FSDFS_Links {#sa_fsdfs_links} + +Each DFS link maps a logical DFS path (e.g. `\\contoso.com\public\sales`) to a physical target path on a specific server. Multiple links may exist per namespace. + +| Column | Type | Size | Nullable | PK | FK | Default | Description | +|---|---|---|---|---|---|---|---| +| ID | int | | No | PK | | IDENTITY(1,1) | Surrogate link ID | +| HOST | int | | No | PK | | | Host partition (the DFS host) | +| NamespaceID | int | | Yes | | FK → SA_FSDFS_Namespaces.ID | | Owning namespace | +| NamespaceName | nvarchar | 512 | No | | | | Cached namespace name | +| DfsPath | nvarchar | 400 | No | | | | DFS-side logical path (e.g. `sales\reports`) | +| DfsResourceID | bigint | | Yes | | FK → SA_FSAA_Resources.ID | | Resource representing the DFS-side path (when available) | +| DfsHostID | int | | Yes | | | | Host on the DFS side | +| TargetPath | nvarchar | 450 | No | | | | UNC path of the physical target (e.g. `\\fileserver\sales`) | +| TargetHostID | int | | Yes | | FK → SA_FSAA_Hosts.ID | | FSAA host that holds the physical target | +| TargetGateID | int | | Yes | | FK → SA_FSAA_Gates.ID | | Gate (share) that holds the physical target | +| TargetResourceID | bigint | | Yes | | FK → SA_FSAA_Resources.ID | | Resource on the target host | +| State | int | | Yes | | | | DFS link state (online / offline) | +| Timeout | int | | Yes | | | | DFS-link cache timeout | +| DfsGuid | uniqueidentifier | | Yes | | | | DFS link's unique identifier | +| Comment | nvarchar | 1024 | Yes | | | | Free-text comment | +| IsRoot | bit | | No | | | | True if this link represents the namespace root rather than a sub-link | + +**Primary Key:** `PK_SA_FSDFS_Links` — clustered on `(HOST, ID)` +**Foreign Keys:** +- `FK_SA_FSDFS_Links_NamespaceID` — `(NamespaceID) → SA_FSDFS_Namespaces(ID) ON DELETE CASCADE` +- `FK_SA_FSDFS_Links_TargetHostID` — `(TargetHostID) → SA_FSAA_Hosts(ID)` +- `FK_SA_FSDFS_Links_TargetGateID` — `(TargetHostID, TargetGateID) → SA_FSAA_Gates(HOST, ID)` +- `FK_SA_FSDFS_Links_TargetResourceID` — `(TargetHostID, TargetResourceID) → SA_FSAA_Resources(HOST, ID)` +- `FK_SA_FSDFS_Links_DfsResourceID` — `(DfsHostID, DfsResourceID) → SA_FSAA_Resources(HOST, ID)` + +**Indexes:** +- `UQ_FSDFS_Links_DfsPath` — unique nonclustered on `(DfsPath, NamespaceID)` +- `SA_FSDFS_Links_GateID_IDX` — nonclustered on `(TargetHostID, TargetGateID)` diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/_category_.json b/docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/_category_.json new file mode 100644 index 0000000000..ef7d5a7c74 --- /dev/null +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Enumeration & Lookup Values", + "position": 40, + "collapsed": true, + "collapsible": true, + "link": { + "type": "doc", + "id": "overview" + } +} diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/overview.md new file mode 100644 index 0000000000..02dcc9ec63 --- /dev/null +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/overview.md @@ -0,0 +1,96 @@ +# Enumeration & Lookup Values + +This page documents all coded column values and lookup tables used in the FSAA DC schema. Views surface most of these codes as human-readable description columns, but the raw values appear in the underlying tables and are useful for writing direct queries or custom reports. + +## TrusteeType {#trusteetype} + +Used in `SA_FSAA_Trustees.TrusteeType` and `SA_FSAA_LocalTrustees.TrusteeType`. Identifies the class of security principal represented by a trustee row. + +| Value | Name | Description | +|---|---|---| +| 0 | Unknown | Type could not be determined | +| 1 | SecurityPrincipal | Built-in / well-known security principal (e.g. `Everyone`) | +| 2 | LocalUser | Local user account | +| 3 | LocalGroup | Local group account | +| 4 | GlobalUser | Domain user account (shown as `Domain User` in views) | +| 5 | GlobalGroup | Domain group account (shown as `Domain Group` in views) | +| 6 | SharepointUser | SharePoint user | +| 7 | SharepointGroup | SharePoint group | +| 8 | Unsupported | Trustee type not supported | +| 9 | ServiceAccount | Service account | +| 10 | Computer | Computer account | +| 11 | GlobalTrustee | Cross-domain trustee | +| 20 | UnixUser | POSIX user | +| 21 | UnixGroup | POSIX group | + +The `TrusteeTypeDescription` column in views covers values 0, 1, 2, 3, 4, 5, 8, 9, and 10. Values 6, 7, 11, 20, and 21 do not have a dedicated description string in the current view CASE expressions. + +## ResourceType {#resourcetype} + +Used in `SA_FSAA_Resources.ResourceType`. Identifies the kind of file-system object the resource row represents. + +| Value | Name | View label | Description | +|---|---|---|---| +| 0 | Share | Share | SMB / Windows share root | +| 1 | NFSExport | Share | NFS export root | +| 2 | NetAppVolume | Folder | NetApp volume root | +| 3 | WinDir | Folder | Windows directory | +| 4 | WinFile | File | Windows file | +| 5 | UnixDir | Folder | Unix directory | +| 6 | UnixFile | File | Unix file | + +Views map these values to three labels using the following logic: + +``` +CASE + WHEN ResourceType IN (0, 1) THEN 'Share' + WHEN ResourceType IN (2, 3, 5) THEN 'Folder' + WHEN ResourceType IN (4, 6) THEN 'File' +END +``` + +## GateType {#gatetype} + +Used in `SA_FSAA_Gates.GateType`. Identifies the protocol or mechanism the gate represents. + +| Value | Description | +|---|---| +| 0 | SMB / Windows share gate | +| 1 | Windows Security Policy gate | +| 2 | NFS v3 export gate | + +All five LSA policy types (Interactive, Batch, Service, Remote Interactive, Network logon) are stored under `GateType = 1`. The specific privilege type is tracked separately in `SA_FSAA_Policies`. These policy gates carry the LSA pseudo-trustee memberships used by `SA_FSAA_GetPolicyMembership` to expand principals such as `NT AUTHORITY\INTERACTIVE` and `NT AUTHORITY\SERVICE`. + +## Rights Bitmask — AllowRights / DenyRights {#rights-bitmask} + +The simplified six-bit FSAA rights model. Used in `SA_FSAA_Rights.AllowRights`, `DenyRights`, `DirectAllowRights`, `InheritedAllowRights`, `DirectDenyRights`, and `InheritedDenyRights`. Views surface these as the `AllowRightsDescription` / `DenyRightsDescription` text columns (e.g. `LRWDMA`). + +| Bit | Hex / Decimal | Letter | Name | +|---|---|---|---| +| 0 | `0x01` (1) | R | Read | +| 1 | `0x02` (2) | W | Write | +| 2 | `0x04` (4) | D | Delete | +| 3 | `0x08` (8) | M | Manage | +| 4 | `0x10` (16) | A | Admin | +| 5 | `0x20` (32) | L | List | + +The `AllowRightsDescription` string is built by appending each letter whose bit is set. For example, a value of `35` (`0x23` = L + R + W) produces `LRW`. + +The full Windows access mask is stored separately in the `*Mask` columns. The following table shows the common mask values decoded by the `AllowMaskDescription` / `DenyMaskDescription` columns in `SA_FSAA_PermissionsView`, `SA_FSAA_DirectPermissionsView`, and `SA_FSAA_InheritedPermissionsView`: + +| Mask (decimal) | Description | +|---|---| +| 0 | None | +| 2032127 | Full Control (allow) | +| 1245631 | Modify | +| 1179817 | Read & Execute (or "List folder contents" when `AllowRights = 32`) | +| 1179785 | Read | +| 1179926 | Write | +| 983551 | Full Control (deny) | +| 197055 | Modify (deny) | +| 1310720 | Change Permissions | +| 1572864 | Take Ownership | +| 1114112 | Delete | +| 1179648 | Read Permissions | + +Additional special-permission decimal values are decoded by an extended `CASE` expression in the permission views; the values listed above cover the most commonly encountered masks. diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/_category_.json b/docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/_category_.json new file mode 100644 index 0000000000..8e87e36269 --- /dev/null +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Table Relationship Diagrams (ERD)", + "position": 10, + "collapsed": true, + "collapsible": true, + "link": { + "type": "doc", + "id": "overview" + } +} diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/overview.md new file mode 100644 index 0000000000..45c9f11bff --- /dev/null +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/overview.md @@ -0,0 +1,178 @@ +# Table Relationship Diagrams (ERD) + +Relationship lines use standard crow's foot notation: a single vertical bar on the parent side and a crow's foot (fork) on the child side means "exactly one parent, zero or more children"; a single bar on each side with an open circle means one-to-zero-or-one (sidecar / extension table). + +:::note +Every core table includes a `HOST INT` column that is a foreign key to `SA_FSAA_Hosts.ID` with `ON DELETE CASCADE`. To keep the sub-diagrams readable, the host fan-out is shown only in the top-level diagrams below; in the other diagrams `HOST` is implicit on every relationship. Three tables are not shown in any diagram because they carry no foreign keys: `SA_FSAA_SchemaVer` (single-row config), `SA_FSAA_ScanHistory` (audit log), and `SA_FSAA_AzureStorageAccounts` (single-column lookup). +::: + +## Top-level Partitioning {#top-level-partitioning} + +`SA_FSAA_Hosts` is the root of the schema. Every other table includes a `HOST` column whose foreign key cascades on delete, so removing a host atomically purges its entire data set. Because the host fan-out spans more than six child tables, it is split into two diagrams below. + +**Core structural and permission tables:** + +```erDiagram + SA_FSAA_Hosts ||--o{ SA_FSAA_ImportHistory : "HOST" + SA_FSAA_Hosts ||--o{ SA_FSAA_Trustees : "HOST" + SA_FSAA_Hosts ||--o{ SA_FSAA_Resources : "HOST" + SA_FSAA_Hosts ||--o{ SA_FSAA_Gates : "HOST" + SA_FSAA_Hosts ||--o{ SA_FSAA_Tags : "HOST" + SA_FSAA_Hosts ||--o{ SA_FSAA_TagKeys : "HOST" +``` + +**Exception, ownership, and Azure tables:** + +```erDiagram + SA_FSAA_Hosts ||--o{ SA_FSAA_TagProxies : "HOST" + SA_FSAA_Hosts ||--o{ SA_FSAA_ExceptionTypes : "HOST" + SA_FSAA_Hosts ||--o{ SA_FSAA_Exceptions : "HOST" + SA_FSAA_Hosts ||--o{ SA_FSAA_ProbableOwners : "HOST" + SA_FSAA_Hosts ||--o{ SA_FSAA_AzureFilesShares : "HOST" +``` + +## Trustees {#trustees} + +`SA_FSAA_Trustees` is the canonical trustee table. `SA_FSAA_LocalTrustees` is a 1:0..1 extension that adds NT-style domain/name/display fields for principals local to the host. `SA_FSAA_TrusteeEquivalence` is the local-group-membership edge table — `TrusteeID` is the member, `EquivalentTrusteeID` is the local group it belongs to. `SA_FSAA_TrusteeMap` is the cross-module identity bridge to the Activity (FSAC) and DLP (FSDLP) trustee tables. + +```erDiagram + SA_FSAA_Trustees ||--o| SA_FSAA_LocalTrustees : "ID (extension)" + SA_FSAA_Trustees ||--o{ SA_FSAA_TrusteeEquivalence : "TrusteeID (member)" + SA_FSAA_LocalTrustees ||--o{ SA_FSAA_TrusteeEquivalence : "EquivalentTrusteeID (group)" + SA_FSAA_Trustees ||--o| SA_FSAA_TrusteeMap : "ID" +``` + +## Resources {#resources} + +`SA_FSAA_Resources` is the file/folder/share tree. Note the self-reference for parent-child folder hierarchy and the `OwnerID` FK back to `SA_FSAA_Trustees`. Five sidecar tables hold per-resource aggregations. `SA_FSAA_ResourceMap` and `SA_FSAA_ResourcesScanTypeDetails` are 1:0..1 extensions that hold cross-module IDs and per-scan-type USN tracking respectively. + +```erDiagram + SA_FSAA_Resources ||--o{ SA_FSAA_Resources : "ParentResourceID (self)" + SA_FSAA_Trustees ||--o{ SA_FSAA_Resources : "OwnerID" + + SA_FSAA_Resources ||--o{ SA_FSAA_FileSizes : "ResourceID" + SA_FSAA_Resources ||--o{ SA_FSAA_FileTypes : "ResourceID" + SA_FSAA_Resources ||--o{ SA_FSAA_FileAges : "ResourceID" + SA_FSAA_Resources ||--o{ SA_FSAA_UnixRights : "ResourceID" + SA_FSAA_Resources ||--o{ SA_FSAA_ProbableOwners : "ResourceID" + + SA_FSAA_Trustees ||--o{ SA_FSAA_UnixRights : "OwnerID + GroupID" + SA_FSAA_Trustees ||--o{ SA_FSAA_ProbableOwners : "OwnerID" + + SA_FSAA_Resources ||--o| SA_FSAA_ResourceMap : "ID (extension)" + SA_FSAA_Resources ||--o| SA_FSAA_ResourcesScanTypeDetails : "ID (extension)" +``` + +## Gates and Permissions {#gates-and-permissions} + +A "gate" is a way to reach a resource — an SMB share, NFS export, or LSA-policy container. `SA_FSAA_Gates` self-references through `PolicyID` (an NFS export gate points at its export-policy gate). `SA_FSAA_GatesProxy` is the dedup bridge between resources and gates. `SA_FSAA_Rights` holds the per-trustee allow/deny ACL entries. `SA_FSAA_GateMap` is the cross-module gate identity bridge. + +```erDiagram + SA_FSAA_Gates ||--o{ SA_FSAA_Gates : "PolicyID (self)" + SA_FSAA_Resources ||--o{ SA_FSAA_Gates : "ShareID + FolderID" + + SA_FSAA_Gates ||--o{ SA_FSAA_GatesProxy : "GateID" + SA_FSAA_Gates ||--o{ SA_FSAA_Policies : "PolicyID" + SA_FSAA_Trustees ||--o{ SA_FSAA_Policies : "TrusteeID" + + SA_FSAA_Trustees ||--o{ SA_FSAA_Rights : "TrusteeID" + + SA_FSAA_Gates ||--o| SA_FSAA_GateMap : "ID (extension)" +``` + +:::note +`SA_FSAA_Resources.RightsProxyID → SA_FSAA_Rights.RightsProxyID` and `SA_FSAA_Resources.GatesProxyID → SA_FSAA_GatesProxy.ID` are logical (un-enforced) references not shown above. These are denormalized pointers maintained by the import pipeline; no FK constraint is created so that bulk imports can stage rows in any order. +::: + +## Tags {#tags} + +Tags use a three-table dedup pattern. `SA_FSAA_Tags` holds each unique tag string. `SA_FSAA_TagKeys` defines a "tag set" identity. `SA_FSAA_TagProxies` is the membership table linking tag sets to their individual tags. `SA_FSAA_Resources.TagProxyID` and `SA_FSAA_FileTags.TagProxyID` reference the tag-set identity in `TagKeys`. + +```erDiagram + SA_FSAA_TagKeys ||--o{ SA_FSAA_TagProxies : "TagProxyID" + SA_FSAA_Tags ||--o{ SA_FSAA_TagProxies : "TagID" + SA_FSAA_TagKeys ||--o{ SA_FSAA_FileTags : "TagProxyID" + SA_FSAA_Resources ||--o{ SA_FSAA_FileTags : "ResourceID" +``` + +## Exceptions {#exceptions} + +`SA_FSAA_ExceptionTypes` is the per-host catalog of exception classes. `SA_FSAA_Exceptions` carries one row per detected anomaly and has FKs to all four foundational tables — Hosts, Gates, Resources, and Trustees (twice: `TrusteeID` and `SourceTrusteeID`). Most FK columns are nullable because different exception types use different combinations. + +```erDiagram + SA_FSAA_ExceptionTypes ||--o{ SA_FSAA_Exceptions : "ExceptionType" + SA_FSAA_Gates ||--o{ SA_FSAA_Exceptions : "GateID" + SA_FSAA_Resources ||--o{ SA_FSAA_Exceptions : "ResourceID" + SA_FSAA_Trustees ||--o{ SA_FSAA_Exceptions : "TrusteeID" + SA_FSAA_Trustees ||--o{ SA_FSAA_Exceptions : "SourceTrusteeID" +``` + +## Azure Files {#azure-files} + +`SA_FSAA_AzureFilesShares` ties an Azure Files share back to the resource tree (`ResourceID` = share root) and the gate model (`GateID`). `SA_FSAA_AzureFilesShareProperties` is a 1:0..1 extension carrying Azure-specific metadata (tier, lease, retention, quota). + +```erDiagram + SA_FSAA_Resources ||--o{ SA_FSAA_AzureFilesShares : "ResourceID" + SA_FSAA_Gates ||--o{ SA_FSAA_AzureFilesShares : "GateID" + SA_FSAA_AzureFilesShares ||--o| SA_FSAA_AzureFilesShareProperties : "AzureShareID (extension)" +``` + +## Activity Collection (SA_FSAC_*) {#activity-collection} + +`SA_FSAC_ActivityEvents` is the audit-event firehose; each row is one observed file-system operation. Every event references the resource (`PathID`), the trustee that performed the operation, and the process (`ProcessID`) that ran it. Three detail tables hang off `ActivityEvents`: `SA_FSAC_PermissionChanges`, `SA_FSAC_OwnerChanges`, and `SA_FSAC_RenameTargets`. `SA_FSAC_DailyActivity` is a daily aggregation rolled up by `(folder, trustee, operation)`. `SA_FSAC_Exceptions` records detected anomalies; `SA_FSAC_UserExceptions` is the per-user variant (partitioned by `SID` instead of by host). + +```erDiagram + SA_FSAA_Hosts ||--o{ SA_FSAC_ProcessNames : "HOST" + SA_FSAA_Hosts ||--o{ SA_FSAC_ActivityEvents : "HOST" + SA_FSAA_Hosts ||--o{ SA_FSAC_DailyActivity : "HOST" + + SA_FSAA_Resources ||--o{ SA_FSAC_ActivityEvents : "PathID" + SA_FSAA_Trustees ||--o{ SA_FSAC_ActivityEvents : "TrusteeID" + SA_FSAC_ProcessNames ||--o{ SA_FSAC_ActivityEvents : "ProcessID" + + SA_FSAC_ActivityEvents ||--o{ SA_FSAC_PermissionChanges : "ActivityID" + SA_FSAC_ActivityEvents ||--o| SA_FSAC_OwnerChanges : "ActivityID" + SA_FSAC_ActivityEvents ||--o| SA_FSAC_RenameTargets : "ActivityID" + + SA_FSAA_Trustees ||--o{ SA_FSAC_PermissionChanges : "TrusteeID" + SA_FSAA_Trustees ||--o{ SA_FSAC_OwnerChanges : "PreviousOwnerID + NewOwnerID" + SA_FSAA_Resources ||--o{ SA_FSAC_RenameTargets : "TargetPathID" + + SA_FSAA_Resources ||--o{ SA_FSAC_DailyActivity : "FolderID" + SA_FSAA_Trustees ||--o{ SA_FSAC_DailyActivity : "TrusteeID" + + SA_FSAC_ExceptionTypes ||--o{ SA_FSAC_Exceptions : "ExceptionType" + SA_FSAC_UserExceptionTypes ||--o{ SA_FSAC_UserExceptions : "ExceptionType (by SID)" +``` + +## Sensitive Data — DLP (SA_FSDLP_*) {#sensitive-data} + +`SA_FSDLP_Criteria` lists the active DLP patterns. `SA_FSDLP_Matches` records, for each `(file, criterion)` pair, how many hits were found. `SA_FSDLP_MatchHits` carries the per-hit excerpt (prefix/data/suffix) and confidence score. `SA_FSDLP_MatchHits_SubjectProfile` links each hit to a subject in the central Subject Profile system. + +```erDiagram + SA_FSAA_Hosts ||--o{ SA_FSDLP_ImportHistory : "HOST" + SA_FSAA_Hosts ||--o{ SA_FSDLP_Criteria : "HOST" + + SA_FSDLP_Criteria ||--o{ SA_FSDLP_Matches : "CriteriaId" + SA_FSDLP_Matches ||--o{ SA_FSDLP_MatchHits : "FileId + CriteriaId" + SA_FSDLP_MatchHits ||--o{ SA_FSDLP_MatchHits_SubjectProfile : "FileId + CriteriaId + ID" +``` + +:::note +`SA_FSDLP_Matches.FileId → SA_FSAA_Resources.ID` is a logical (un-enforced) reference not shown above. The DLP collector populates `FileId` to match the FSAA resource ID but no SQL FK constraint is created, so DLP imports can run independently of structural scans. `SA_FSDLP_MatchHits_SubjectProfile` also has foreign keys into the central Subject Profile tables (`SA_SubjectProfile_Sources`, `SA_SubjectProfile_Identities`, `SA_SubjectProfile_AttributeValues`), which are owned by a separate module and not shown here. +::: + +## DFS Namespaces (SA_FSDFS_*) {#dfs-namespaces} + +`SA_FSDFS_Namespaces` lists the discovered DFS namespaces. `SA_FSDFS_Links` resolves each DFS-side path into the physical target (host/gate/resource) on a real file server. The link table has FKs into both the FSAA host and the FSAA structural tables on the target side. + +```erDiagram + SA_FSAA_Hosts ||--o{ SA_FSDFS_Namespaces : "RootHostID" + SA_FSAA_Gates ||--o{ SA_FSDFS_Namespaces : "(RootHostID, RootGateID) composite FK" + + SA_FSDFS_Namespaces ||--o{ SA_FSDFS_Links : "NamespaceID" + SA_FSAA_Hosts ||--o{ SA_FSDFS_Links : "TargetHostID" + SA_FSAA_Gates ||--o{ SA_FSDFS_Links : "TargetGateID" + SA_FSAA_Resources ||--o{ SA_FSDFS_Links : "TargetResourceID" + SA_FSAA_Resources ||--o{ SA_FSDFS_Links : "DfsResourceID" +``` diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/fkreference/_category_.json b/docs/accessanalyzer/12.0/admin/schema/fsaadc/fkreference/_category_.json new file mode 100644 index 0000000000..c990fe38d8 --- /dev/null +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/fkreference/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Foreign Key Reference", + "position": 70, + "collapsed": true, + "collapsible": true, + "link": { + "type": "doc", + "id": "overview" + } +} diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/fkreference/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/fkreference/overview.md new file mode 100644 index 0000000000..eb433b9ab5 --- /dev/null +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/fkreference/overview.md @@ -0,0 +1,87 @@ +# Foreign Key Reference + +## Complete Foreign Key Listing {#complete-foreign-key-listing} + +All enforced FK constraints across the four FSAA DC collector modules, listed in the same order as the [Core Data Collection Tables](../coretables/overview.md) page. + +| FK Name | Parent Table | Parent Column(s) | Referenced Table | Referenced Column(s) | On Delete | +|---|---|---|---|---|---| +| FK_SA_FSAA_ImportHistory_HOST | SA_FSAA_ImportHistory | HOST | SA_FSAA_Hosts | ID | CASCADE | +| FK_SA_FSAA_Trustees_HOST | SA_FSAA_Trustees | HOST | SA_FSAA_Hosts | ID | CASCADE | +| FK_SA_FSAA_LocalTrustees_ID | SA_FSAA_LocalTrustees | HOST, ID | SA_FSAA_Trustees | HOST, ID | CASCADE | +| FK_SA_FSAA_TrusteeEquivalence_TrusteeID | SA_FSAA_TrusteeEquivalence | HOST, TrusteeID | SA_FSAA_Trustees | HOST, ID | NO ACTION | +| FK_SA_FSAA_TrusteeEquivalence_EquivalentTrusteeID | SA_FSAA_TrusteeEquivalence | HOST, EquivalentTrusteeID | SA_FSAA_LocalTrustees | HOST, ID | CASCADE | +| FK_SA_FSAA_Rights_TrusteeID | SA_FSAA_Rights | HOST, TrusteeID | SA_FSAA_Trustees | HOST, ID | NO ACTION | +| FK_SA_FSAA_Tags_HOST | SA_FSAA_Tags | HOST | SA_FSAA_Hosts | ID | CASCADE | +| FK_SA_FSAA_TagKeys_HOST | SA_FSAA_TagKeys | HOST | SA_FSAA_Hosts | ID | CASCADE | +| FK_SA_FSAA_TagProxies_HOST | SA_FSAA_TagProxies | HOST | SA_FSAA_Hosts | ID | CASCADE | +| FK_SA_FSAA_TagProxies_TagProxyID | SA_FSAA_TagProxies | HOST, TagProxyID | SA_FSAA_TagKeys | HOST, TagProxyID | NO ACTION | +| FK_SA_FSAA_TagProxies_TagID | SA_FSAA_TagProxies | HOST, TagID | SA_FSAA_Tags | HOST, TagID | NO ACTION | +| FK_SA_FSAA_Resources_HOST | SA_FSAA_Resources | HOST | SA_FSAA_Hosts | ID | CASCADE | +| FK_SA_FSAA_Resources_ParentResourceID | SA_FSAA_Resources | HOST, ParentResourceID | SA_FSAA_Resources | HOST, ID | NO ACTION | +| FK_SA_FSAA_Resources_OwnerID | SA_FSAA_Resources | HOST, OwnerID | SA_FSAA_Trustees | HOST, ID | NO ACTION | +| FK_SA_FSAA_UnixRights_ResourceID | SA_FSAA_UnixRights | HOST, ResourceID | SA_FSAA_Resources | HOST, ID | CASCADE | +| FK_SA_FSAA_UnixRights_OwnerID | SA_FSAA_UnixRights | HOST, OwnerID | SA_FSAA_Trustees | HOST, ID | NO ACTION | +| FK_SA_FSAA_UnixRights_GroupID | SA_FSAA_UnixRights | HOST, GroupID | SA_FSAA_Trustees | HOST, ID | NO ACTION | +| FK_SA_FSAA_Gates_HOST | SA_FSAA_Gates | HOST | SA_FSAA_Hosts | ID | CASCADE | +| FK_SA_FSAA_Gates_ShareID | SA_FSAA_Gates | HOST, ShareID | SA_FSAA_Resources | HOST, ID | NO ACTION | +| FK_SA_FSAA_Gates_FolderID | SA_FSAA_Gates | HOST, FolderID | SA_FSAA_Resources | HOST, ID | NO ACTION | +| FK_SA_FSAA_Gates_PolicyID | SA_FSAA_Gates | HOST, PolicyID | SA_FSAA_Gates | HOST, ID | NO ACTION | +| FK_SA_FSAA_GatesProxy_GateID | SA_FSAA_GatesProxy | HOST, GateID | SA_FSAA_Gates | HOST, ID | CASCADE | +| FK_SA_FSAA_Policies_PolicyID | SA_FSAA_Policies | HOST, PolicyID | SA_FSAA_Gates | HOST, ID | CASCADE | +| FK_SA_FSAA_Policies_TrusteeID | SA_FSAA_Policies | HOST, TrusteeID | SA_FSAA_Trustees | HOST, ID | NO ACTION | +| FK_SA_FSAA_Exceptions_HOST | SA_FSAA_Exceptions | HOST | SA_FSAA_Hosts | ID | NO ACTION | +| FK_SA_FSAA_Exceptions_GateID | SA_FSAA_Exceptions | HOST, GateID | SA_FSAA_Gates | HOST, ID | CASCADE | +| FK_SA_FSAA_Exceptions_ResourceID | SA_FSAA_Exceptions | HOST, ResourceID | SA_FSAA_Resources | HOST, ID | NO ACTION | +| FK_SA_FSAA_Exceptions_TrusteeID | SA_FSAA_Exceptions | HOST, TrusteeID | SA_FSAA_Trustees | HOST, ID | NO ACTION | +| FK_SA_FSAA_Exceptions_SourceTrusteeID | SA_FSAA_Exceptions | HOST, SourceTrusteeID | SA_FSAA_Trustees | HOST, ID | NO ACTION | +| FK_SA_FSAA_ExceptionTypes_HOST | SA_FSAA_ExceptionTypes | HOST | SA_FSAA_Hosts | ID | CASCADE | +| FK_SA_FSAA_ProbableOwners_HOST | SA_FSAA_ProbableOwners | HOST | SA_FSAA_Hosts | ID | CASCADE | +| FK_SA_FSAA_ProbableOwners_ResourceID | SA_FSAA_ProbableOwners | HOST, ResourceID | SA_FSAA_Resources | HOST, ID | NO ACTION | +| FK_SA_FSAA_ProbableOwners_OwnerID | SA_FSAA_ProbableOwners | HOST, OwnerID | SA_FSAA_Trustees | HOST, ID | NO ACTION | +| FK_SA_FSAA_FileSizes_ResourceID | SA_FSAA_FileSizes | HOST, ResourceID | SA_FSAA_Resources | HOST, ID | CASCADE | +| FK_SA_FSAA_FileTypes_ResourceID | SA_FSAA_FileTypes | HOST, ResourceID | SA_FSAA_Resources | HOST, ID | CASCADE | +| FK_SA_FSAA_FileAges_ResourceID | SA_FSAA_FileAges | HOST, ResourceID | SA_FSAA_Resources | HOST, ID | CASCADE | +| FK_SA_FSAA_FileTags_ResourceID | SA_FSAA_FileTags | HOST, ResourceID | SA_FSAA_Resources | HOST, ID | CASCADE | +| FK_SA_FSAA_FileTags_TagProxyID | SA_FSAA_FileTags | HOST, TagProxyID | SA_FSAA_TagKeys | HOST, TagProxyID | NO ACTION | +| FK_SA_FSAA_AzureFilesShares_HOST | SA_FSAA_AzureFilesShares | HOST | SA_FSAA_Hosts | ID | CASCADE | +| FK_SA_FSAA_AzureFilesShares_ResourceID | SA_FSAA_AzureFilesShares | HOST, ResourceID | SA_FSAA_Resources | HOST, ID | NO ACTION | +| FK_SA_FSAA_AzureFilesShares_GateID | SA_FSAA_AzureFilesShares | HOST, GateID | SA_FSAA_Gates | HOST, ID | NO ACTION | +| FK_SA_FSAA_AzureFilesShareProperties_AzureShareID | SA_FSAA_AzureFilesShareProperties | HOST, AzureShareID | SA_FSAA_AzureFilesShares | HOST, ID | CASCADE | +| FK_SA_FSAA_TrusteeMap_ID | SA_FSAA_TrusteeMap | HOST, ID | SA_FSAA_Trustees | HOST, ID | NO ACTION | +| FK_SA_FSAA_ResourceMap_ID | SA_FSAA_ResourceMap | HOST, ID | SA_FSAA_Resources | HOST, ID | NO ACTION | +| FK_SA_FSAA_GateMap_ID | SA_FSAA_GateMap | HOST, ID | SA_FSAA_Gates | HOST, ID | NO ACTION | +| FK_SA_FSAA_ResourcesScanTypeDetails_ID | SA_FSAA_ResourcesScanTypeDetails | HOST, ID | SA_FSAA_Resources | HOST, ID | NO ACTION | +| FK_SA_FSAC_ProcessNames_HOST | SA_FSAC_ProcessNames | HOST | SA_FSAA_Hosts | ID | CASCADE | +| FK_SA_FSAC_ActivityEvents_HOST | SA_FSAC_ActivityEvents | HOST | SA_FSAA_Hosts | ID | CASCADE | +| FK_SA_FSAC_ActivityEvents_PathID | SA_FSAC_ActivityEvents | HOST, PathID | SA_FSAA_Resources | HOST, ID | NO ACTION | +| FK_SA_FSAC_ActivityEvents_ProcessID | SA_FSAC_ActivityEvents | HOST, ProcessID | SA_FSAC_ProcessNames | HOST, ID | NO ACTION | +| FK_SA_FSAC_ActivityEvents_TrusteeID | SA_FSAC_ActivityEvents | HOST, TrusteeID | SA_FSAA_Trustees | HOST, ID | NO ACTION | +| FK_SA_FSAC_PermissionChanges_HOST | SA_FSAC_PermissionChanges | HOST | SA_FSAA_Hosts | ID | NO ACTION | +| FK_SA_FSAC_PermissionChanges_ActivityID | SA_FSAC_PermissionChanges | HOST, ActivityID | SA_FSAC_ActivityEvents | HOST, ID | NO ACTION | +| FK_SA_FSAC_PermissionChanges_TrusteeID | SA_FSAC_PermissionChanges | HOST, TrusteeID | SA_FSAA_Trustees | HOST, ID | NO ACTION | +| FK_SA_FSAC_OwnerChanges_HOST | SA_FSAC_OwnerChanges | HOST | SA_FSAA_Hosts | ID | NO ACTION | +| FK_SA_FSAC_OwnerChanges_ActivityID | SA_FSAC_OwnerChanges | HOST, ActivityID | SA_FSAC_ActivityEvents | HOST, ID | NO ACTION | +| FK_SA_FSAC_OwnerChanges_PreviousOwnerID | SA_FSAC_OwnerChanges | HOST, PreviousOwnerID | SA_FSAA_Trustees | HOST, ID | NO ACTION | +| FK_SA_FSAC_OwnerChanges_NewOwnerID | SA_FSAC_OwnerChanges | HOST, NewOwnerID | SA_FSAA_Trustees | HOST, ID | NO ACTION | +| FK_SA_FSAC_DailyActivity_HOST | SA_FSAC_DailyActivity | HOST | SA_FSAA_Hosts | ID | CASCADE | +| FK_SA_FSAC_DailyActivity_FolderID | SA_FSAC_DailyActivity | HOST, FolderID | SA_FSAA_Resources | HOST, ID | NO ACTION | +| FK_SA_FSAC_DailyActivity_TrusteeID | SA_FSAC_DailyActivity | HOST, TrusteeID | SA_FSAA_Trustees | HOST, ID | NO ACTION | +| FK_SA_FSAC_RenameTargets_HOST | SA_FSAC_RenameTargets | HOST | SA_FSAA_Hosts | ID | CASCADE | +| FK_SA_FSAC_RenameTargets_ActivityID | SA_FSAC_RenameTargets | HOST, ActivityID | SA_FSAC_ActivityEvents | HOST, ID | NO ACTION | +| FK_SA_FSAC_RenameTargets_TargetPathID | SA_FSAC_RenameTargets | HOST, TargetPathID | SA_FSAA_Resources | HOST, ID | NO ACTION | +| FK_SA_FSDLP_ImportHistory_HOST | SA_FSDLP_ImportHistory | HOST | SA_FSAA_Hosts | ID | CASCADE | +| FK_SA_FSDLP_Criteria_HOST | SA_FSDLP_Criteria | HOST | SA_FSAA_Hosts | ID | CASCADE | +| FK_SA_FSDLP_Matches_CriteriaId | SA_FSDLP_Matches | HOST, CriteriaId | SA_FSDLP_Criteria | HOST, ID | CASCADE | +| FK_SA_FSDLP_MatchHits_Match | SA_FSDLP_MatchHits | HOST, FileId, CriteriaId | SA_FSDLP_Matches | HOST, FileId, CriteriaId | CASCADE | +| FK_SA_FSDLP_MatchHits_SubjectProfile | SA_FSDLP_MatchHits_SubjectProfile | HOST, FileId, CriteriaId, ID | SA_FSDLP_MatchHits | HOST, FileId, CriteriaId, ID | CASCADE | +| FK_SA_FSDLP_MatchHits_SubjectProfile_Source | SA_FSDLP_MatchHits_SubjectProfile | SourceId | SA_SubjectProfile_Sources | Id | NO ACTION | +| FK_SA_FSDLP_MatchHits_SubjectProfile_Identity | SA_FSDLP_MatchHits_SubjectProfile | IdentityId | SA_SubjectProfile_Identities | Id | NO ACTION | +| FK_SA_FSDLP_MatchHits_SubjectProfile_Attribute | SA_FSDLP_MatchHits_SubjectProfile | IdentityId, AttributeId, Order | SA_SubjectProfile_AttributeValues | IdentityId, AttributeId, Order | CASCADE | +| FK_SA_FSDFS_Namespaces_Hosts | SA_FSDFS_Namespaces | RootHostID | SA_FSAA_Hosts | ID | CASCADE | +| FK_SA_FSDFS_Namespaces_GateID | SA_FSDFS_Namespaces | RootHostID, RootGateID | SA_FSAA_Gates | HOST, ID | NO ACTION | +| FK_SA_FSDFS_Links_NamespaceID | SA_FSDFS_Links | NamespaceID | SA_FSDFS_Namespaces | ID | CASCADE | +| FK_SA_FSDFS_Links_TargetHostID | SA_FSDFS_Links | TargetHostID | SA_FSAA_Hosts | ID | NO ACTION | +| FK_SA_FSDFS_Links_TargetGateID | SA_FSDFS_Links | TargetHostID, TargetGateID | SA_FSAA_Gates | HOST, ID | NO ACTION | +| FK_SA_FSDFS_Links_TargetResourceID | SA_FSDFS_Links | TargetHostID, TargetResourceID | SA_FSAA_Resources | HOST, ID | NO ACTION | +| FK_SA_FSDFS_Links_DfsResourceID | SA_FSDFS_Links | DfsHostID, DfsResourceID | SA_FSAA_Resources | HOST, ID | NO ACTION | diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/functions/_category_.json b/docs/accessanalyzer/12.0/admin/schema/fsaadc/functions/_category_.json new file mode 100644 index 0000000000..7b82af05dc --- /dev/null +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/functions/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Functions & Stored Procedures", + "position": 50, + "collapsed": true, + "collapsible": true, + "link": { + "type": "doc", + "id": "overview" + } +} diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/functions/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/functions/overview.md new file mode 100644 index 0000000000..ab1560e309 --- /dev/null +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/functions/overview.md @@ -0,0 +1,216 @@ +# Functions & Stored Procedures + +All functions and stored procedures live in the `dbo` schema. Most table-valued functions are inline (iTVF) and are joined into views with `CROSS APPLY` or `OUTER APPLY`. Two cross-database UDF table types — `SA_CORE_GroupMemberPathTable` and `SA_CORE_GroupMembersTable` — are used as `READONLY` table-valued parameters; both come from the `SA_CORE_*` shared schema created elsewhere. + +## FSAA Functions {#fsaa-functions} + +### SA_FSAA_GetPath + +**Signature:** `(@serverID INT, @resourceID BIGINT) RETURNS NVARCHAR(4000)` +**Type:** Scalar function + +Walks the parent chain in `SA_FSAA_Resources` and concatenates names with the appropriate delimiter (`/` for Unix resources of type 5 or 6, `\` for everything else) to produce the full resource path. Returns NULL if the resource is not found. + +### SA_FSAA_GetTrusteeMembership + +**Signature:** `(@serverID INT, @objectSID VARCHAR(184), @trusteeType INT, @groupPath SA_CORE_GroupMemberPathTable READONLY, @directlyApplied INT = 0, @membershipOverride SA_CORE_GroupMembersTable READONLY) RETURNS TABLE (NTDomain, NTName, DisplayName, ObjectSID, TrusteeType)` +**Type:** Multi-statement table-valued function + +Recursively expands a group or principal into its effective members. Handles well-known SIDs specially — `S-1-5-2 NETWORK`, `S-1-5-3 BATCH`, `S-1-5-4 INTERACTIVE`, `S-1-5-6 SERVICE`, `S-1-5-13 TERMINAL SERVER USER`, `S-1-5-14 REMOTE INTERACTIVE LOGON`, `S-1-2-0 LOCAL` — by routing through `SA_FSAA_GetPolicyMembership`. Domain groups are expanded via `SA_CORE_GetDomainGroupMembershipEx` or `SA_ADInventory_GroupMembersView`; local groups via `SA_FSAA_GetLocalGroupMembership`. The `@groupPath` parameter prevents infinite recursion. + +### SA_FSAA_IsTrusteeMember + +**Signature:** `(@serverID INT, @trusteeSID VARCHAR(184), @trusteeDomain NVARCHAR(256), @trusteeType INT, @groupSID VARCHAR(184), @groupDomain NVARCHAR(256), @groupType INT, @directlyApplied INT) RETURNS INT` +**Type:** Scalar function + +Returns `1` if the trustee is a recursive member of the group, else `0`. Encodes fast paths for `Everyone (S-1-1-0)`, `Authenticated Users (S-1-5-11)` (excluding Guest, Anonymous, and Domain Computers), and `Domain Users (S-1-5-21-...-513)`. Falls back to `SA_FSAA_GetTrusteeMembership` when the relationship cannot be answered by a fast path. + +### SA_FSAA_RecurseFolders + +**Signature:** `(@serverID INT, @resourceID BIGINT) RETURNS TABLE (ID, NestedLevel, ResourceType, DeletedUSN)` +**Type:** Inline table-valued function (recursive CTE) + +Returns every descendant of the given resource. Used for subtree aggregation queries. + +### SA_FSAA_WalkTrusteePath + +**Signature:** `(@serverID INT, @trusteeType INT, @trusteeSID VARCHAR(184), @trusteeDomain NVARCHAR(256), @trusteeDisplay NVARCHAR(256), @groupSID VARCHAR(184), @groupType INT, @groupDomain NVARCHAR(256), @groupName NVARCHAR(256), @pathString NVARCHAR(1024), ...) RETURNS TABLE` +**Type:** Inline table-valued function + +Helper that walks an effective-membership path and accumulates the membership chain into a textual breadcrumb (`group → subgroup → user`). + +### SA_FSAA_GetTrusteeInformationEx + +**Signature:** `(@serverID INT, @trusteeID INT, @objectSID VARCHAR(184), @trusteeType SMALLINT) RETURNS TABLE (NTDomain, NTName, DisplayName, SID, TrusteeType, IsHistoricalSID, PrincipalId)` +**Type:** Inline table-valued function + +Returns a single row of trustee identity. For local trustees the values come from `SA_FSAA_LocalTrustees`; for domain trustees they come from the AD inventory's `SA_ADInventory_*` tables matched by SID (handling SID History when `IsHistoricalSID = 1`). Two definitions exist in the script; the current version is chosen at runtime by the `#SA_ImportObject` helper. + +### SA_FSAA_GetTrusteeInformation + +**Signature:** `(@serverID INT, @trusteeID INT) RETURNS TABLE (NTDomain, NTName, DisplayName, SID, TrusteeType, IsHistoricalSID, PrincipalId)` +**Type:** Inline table-valued function + +Wrapper around `SA_FSAA_GetTrusteeInformationEx` that pulls the SID and `TrusteeType` from `SA_FSAA_Trustees` first. + +### SA_FSAA_GetResourcePermissions + +**Signature:** `(@serverID INT, @resourceID BIGINT) RETURNS TABLE (AllowRights, DenyRights, AllowMask, DenyMask, TrusteeID, NTDomain, NTName, DisplayName, SID, TrusteeType)` +**Type:** Inline table-valued function + +Joins `Resources → Rights → LocalTrustees` and returns the ACL of the resource as a flat table (one row per ACE). + +### SA_FSAA_GetGatePermissions + +**Signature:** `(@serverID INT, @gateID INT) RETURNS TABLE (AllowRights, DenyRights, TrusteeID, NTDomain, NTName, DisplayName, SID, TrusteeType)` +**Type:** Inline table-valued function + +Returns the share-level permissions for a gate. Computes the synthetic Allow/Deny bits by `b.Allow * -63` (turning the boolean into the full 6-bit `LRWDMA` mask). + +### SA_FSAA_GetExpandedPermissions + +**Signature:** `(@serverID INT, @resourceID BIGINT, @ispolicy BIT, @membershipOverride SA_CORE_GroupMembersTable READONLY) RETURNS @expandedRights TABLE (AllowRights, DenyRights, ...trustee columns...)` +**Type:** Multi-statement table-valued function + +Takes a resource's ACL and recursively expands every group ACE into per-leaf-trustee entries via `SA_FSAA_GetTrusteeMembership`. Used by `SA_FSAA_ExpandedPermissionsView`. + +### SA_FSAA_GetExpandedPermissionsEx + +**Signature:** `(@serverID INT, @resourceID BIGINT, @ispolicy INT, @trusteeFilter SA_CORE_TrusteeInformationTable READONLY, @membershipOverride SA_CORE_GroupMembersTable READONLY) RETURNS @expandedRights TABLE (...)` +**Type:** Multi-statement table-valued function + +Same as `SA_FSAA_GetExpandedPermissions` but pre-filtered to only the trustees in `@trusteeFilter`. Significantly faster when the caller cares about a specific user. + +### SA_FSAA_GetExpandedAzureSharePermissions + +**Signature:** `(@serverId INT, @azureShareId BIGINT) RETURNS @expandedRights TABLE (AllowRights, DenyRights, TrusteeDomain, TrusteeNTName, ...)` +**Type:** Multi-statement table-valued function + +Azure-Files-specific equivalent of `SA_FSAA_GetExpandedPermissions`. + +### SA_FSAA_GetPolicyMembership + +**Signature:** `(@serverID INT, @policyID INT, @groupPath SA_CORE_GroupMemberPathTable READONLY, @directlyApplied INT = 0, @membershipOverride SA_CORE_GroupMembersTable READONLY) RETURNS @effectiveMembers TABLE (...)` +**Type:** Multi-statement table-valued function + +Resolves the trustees of a local-policy gate (e.g. *Logon Interactively*). Reads `SA_FSAA_Policies` and recursively expands each policy member. + +### SA_FSAA_GetLocalGroupMembership + +**Signature:** `(@serverID INT, @objectSID VARCHAR(184), @groupPath SA_CORE_GroupMemberPathTable READONLY, @directlyApplied INT = 0, @membershipOverride SA_CORE_GroupMembersTable READONLY) RETURNS @effectiveMembers TABLE (...)` +**Type:** Multi-statement table-valued function + +Walks `SA_FSAA_TrusteeEquivalence` for the given local group and recursively expands each equivalent trustee. + +### SA_FSAA_GetEffectiveRights + +**Signature:** `(@serverID INT, @resourceID BIGINT, @gateID INT, @directlyApplied INT, @membershipOverride SA_CORE_GroupMembersTable READONLY) RETURNS @effectiveRights TABLE (AllowRights, DenyRights, ...trustee columns..., DirectTrustee BIT)` +**Type:** Multi-statement table-valued function + +Computes the effective allow/deny bits for every leaf trustee that can reach the resource through the gate. Composes share permissions, NTFS permissions, group membership expansion, and domain inventory data. The heaviest UDF in the schema. Used by `SA_FSAA_EffectiveAccessView`. + +### SA_FSAA_GetEffectiveRightsEx + +**Signature:** `(@serverID INT, @resourceID BIGINT, @gateID INT, @trusteeFilter SA_CORE_TrusteeInformationTable READONLY, @membershipOverride SA_CORE_GroupMembersTable READONLY) RETURNS @effectiveRights TABLE (...)` +**Type:** Multi-statement table-valued function + +Same as `SA_FSAA_GetEffectiveRights` but filtered to a specific set of trustees. + +### SA_FSAA_GetTrusteePermissionSource + +**Signature:** `(@serverID INT, @resourceID BIGINT, @gateID INT, @trusteeSID VARCHAR(184)) RETURNS @permissionSource TABLE (HOST VARCHAR(64) NOT NULL, AllowRights, DenyRights, AllowRightsDescription, ...)` +**Type:** Multi-statement table-valued function + +Given a resource, gate, and trustee SID, returns the source ACEs that contribute to that trustee's effective rights. Useful for "who granted this user access?" diagnostic UI. + +### SA_FSAA_LookupResourcePath + +**Signature:** `(@serverID INT, @path NVARCHAR(1024)) RETURNS BIGINT` +**Type:** Scalar function + +Resolves a backslash-delimited path string against the resource tree for a host and returns the matching `SA_FSAA_Resources.ID`, or NULL if no match. + +### SA_FSAA_LookupUncPath + +**Signature:** `(@path NVARCHAR(1024)) RETURNS @results TABLE (HostID INT NOT NULL, HostName NVARCHAR(256) NOT NULL, GateID INT NOT NULL, ResourceID BIGINT NULL, ...)` +**Type:** Multi-statement table-valued function + +Parses a UNC path (`\\server\share\path`) and returns the matching host, gate, and resource. Used to map paths captured in DLP or Activity tables back into the FSAA structural keyspace. + +### SA_FSAA_UpdateStatistics + +**Signature:** `()` +**Type:** Stored procedure (no parameters) + +Runs `UPDATE STATISTICS` on the FSAA tables. Invoked by the structural-import job after a bulk import to keep the SQL Server query optimizer's row-count estimates current. Long-running on large data sets. + +## Activity Collector Functions {#activity-collector-functions} + +### SA_FSAC_GetActiveFolderPermissions + +**Signature:** `(@serverID INT, @resourceID BIGINT, @activityDays INT) RETURNS @results TABLE (AllowRights, ActiveRights, AllowRightsDescription, ActiveRightsDescription, TrusteeID, NTDomain, NTName, DisplayName, ObjectSID, TrusteeType)` +**Type:** Multi-statement table-valued function + +For a given resource and a recent activity window (`@activityDays`), returns each trustee's `AllowRights` (statically granted) alongside `ActiveRights` (the subset of those rights the trustee has actually exercised). The "active" mask is computed by walking the resource's subtree of recent daily activity through `SA_FSAC_GetFolderActivityMask`, then ANDing it with the granted rights. Drives the *Least Privileged Access* report. + +### SA_FSAC_GetFolderActivityMask + +**Signature:** `(@serverID INT, @resourceID BIGINT, @activityDays INT) RETURNS @results TABLE (ActiveRights, ActiveRightsDescription, TrusteeID, NTDomain, NTName, DisplayName, ObjectSID, TrusteeType)` +**Type:** Multi-statement table-valued function + +Translates a user's recent activity (within `@activityDays` days) on a folder subtree into the equivalent rights bitmask. Each operation type maps to a specific right: Read → R, Add/Update/Rename → W, Delete → D, PermissionChange → M; any activity at all also implies List (L). Returns one row per user with the consolidated `ActiveRights` mask and identity columns from `SA_FSAA_GetTrusteeInformation`. + +## DFS Functions {#dfs-functions} + +### SA_FSDFS_LookupDfsPath + +**Signature:** `(@path NVARCHAR(1024)) RETURNS @values TABLE (TargetHostID INT, TargetGateID INT, TargetResourceID BIGINT, TargetFolderPath NVARCHAR(1024) NOT NULL)` +**Type:** Multi-statement table-valued function + +Resolves a DFS-style path (e.g. `\\contoso.com\public\sales\reports`) by walking `SA_FSDFS_Links` to find the matching link and returning the underlying physical target — the host, gate, resource, and remaining sub-folder path beneath the link. Used to translate DFS-relative report rows back into FSAA structural identifiers. + +## Shared Core Functions {#shared-core-functions} + +These functions are created by the FSAA Create-Schema job (Task 26) but live in the shared `dbo` schema used across multiple data collector modules. They handle domain group membership expansion and trustee-permission resolution by integrating with AD Inventory tables. + +### SA_CORE_GetDomainGroupMembershipEx + +**Signature:** `(@objectSID VARCHAR(184), @serverID INT, @groupPath SA_CORE_GroupMemberPathTable READONLY) RETURNS @members TABLE (NTDomain, NTName, DisplayName, ObjectSID, TrusteeType)` +**Type:** Multi-statement table-valued function + +Recursively expands a domain group into its members by querying `SA_ADInventory_GroupMembersView`. The `@groupPath` parameter prevents infinite recursion. Returns one row per effective leaf member. + +### SA_CORE_GetDomainGroupMembership + +**Signature:** `(@objectSID VARCHAR(184), @serverID INT, @groupPath SA_CORE_GroupMemberPathTable READONLY) RETURNS @members TABLE (NTDomain, NTName, DisplayName, ObjectSID, TrusteeType)` +**Type:** Multi-statement table-valued function + +Simplified variant of `SA_CORE_GetDomainGroupMembershipEx`. Expands a domain group via the AD Inventory view without the extended membership path handling. + +### SA_CORE_IsTrusteeMember + +**Signature:** `(@trusteeSID VARCHAR(184), @groupSID VARCHAR(184), @serverID INT) RETURNS INT` +**Type:** Scalar function + +Returns `1` if the trustee (identified by `@trusteeSID`) is a recursive member of the group (identified by `@groupSID`), otherwise `0`. Uses `SA_CORE_GetDomainGroupMembershipEx` for the expansion. + +### SA_CORE_GetTrusteePermissionEx + +**Signature:** `(@serverID INT, @resourceID BIGINT, @trusteeFilter SA_CORE_TrusteeInformationTable READONLY, @membershipOverride SA_CORE_GroupMembersTable READONLY) RETURNS @permissions TABLE (AllowRights, DenyRights, ...trustee columns...)` +**Type:** Multi-statement table-valued function + +Returns the effective permissions for a specific set of trustees on a resource, filtering the ACL expansion through `@trusteeFilter`. Designed as the cross-module equivalent of `SA_FSAA_GetExpandedPermissionsEx` for use in contexts where only selected trustees are required. + +### SA_CORE_GetTrusteePermission + +**Signature:** `(@serverID INT, @resourceID BIGINT, @membershipOverride SA_CORE_GroupMembersTable READONLY) RETURNS @permissions TABLE (AllowRights, DenyRights, ...trustee columns...)` +**Type:** Multi-statement table-valued function + +Unfiltered variant of `SA_CORE_GetTrusteePermissionEx` — returns effective permissions for all trustees on the resource. Used when the caller needs the full expanded ACL rather than a targeted subset. + +### SA_CORE_GetEntraTrusteePermissionEx + +**Signature:** `(@serverID INT, @azureShareId BIGINT, @trusteeFilter SA_CORE_TrusteeInformationTable READONLY) RETURNS @permissions TABLE (AllowRights, DenyRights, ...trustee columns...)` +**Type:** Multi-statement table-valued function + +Azure-Files / Entra ID variant of `SA_CORE_GetTrusteePermissionEx`. Resolves effective permissions on an Azure Files share (identified by `@azureShareId`) against the Entra role assignments in `SA_Entra_RmResources`. Only meaningful in Entra-integrated environments. diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/indexreference/_category_.json b/docs/accessanalyzer/12.0/admin/schema/fsaadc/indexreference/_category_.json new file mode 100644 index 0000000000..4e9158bae9 --- /dev/null +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/indexreference/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Index Reference", + "position": 60, + "collapsed": true, + "collapsible": true, + "link": { + "type": "doc", + "id": "overview" + } +} diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/indexreference/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/indexreference/overview.md new file mode 100644 index 0000000000..f34c9b799a --- /dev/null +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/indexreference/overview.md @@ -0,0 +1,75 @@ +# Index Reference + +## Complete Index Listing {#complete-index-listing} + +All indexes across the four FSAA DC collector modules. Clustered primary-key indexes are listed alongside nonclustered supporting indexes. Tables with no indexes beyond their clustered PK are noted at the end of this page. + +| Table | Index Name | Type | Unique | Columns | +|---|---|---|---|---| +| SA_FSAA_Hosts | PK_SA_FSAA_Hosts | Clustered | Yes | ID | +| SA_FSAA_Hosts | UQ_SA_FSAA_Hosts_HOST | Nonclustered | Yes | HOST | +| SA_FSAA_ImportHistory | PK_SA_FSAA_ImportHistory | Clustered | Yes | HOST, ImportTime | +| SA_FSAA_Trustees | PK_SA_FSAA_Trustees | Clustered | Yes | HOST, ID | +| SA_FSAA_LocalTrustees | PK_SA_FSAA_LocalTrustees | Clustered | Yes | HOST, ID | +| SA_FSAA_TrusteeEquivalence | PK_SA_FSAA_TrusteeEquivalence | Clustered | Yes | HOST, TrusteeID, EquivalentTrusteeID | +| SA_FSAA_TrusteeEquivalence | SA_FSAA_TrusteeEquivalence_Group_IDX | Nonclustered | No | HOST, EquivalentTrusteeID; INCLUDE TrusteeID | +| SA_FSAA_Rights | PK_SA_FSAA_Rights | Clustered | Yes | HOST, RightsProxyID, TrusteeID | +| SA_FSAA_Tags | PK_SA_FSAA_Tags | Clustered | Yes | HOST, TagID | +| SA_FSAA_TagKeys | PK_SA_FSAA_TagKeys | Clustered | Yes | HOST, TagProxyID | +| SA_FSAA_TagProxies | PK_SA_FSAA_TagProxies | Clustered | Yes | HOST, TagProxyID, TagID | +| SA_FSAA_Resources | PK_SA_FSAA_Resources | Clustered | Yes | HOST, ID | +| SA_FSAA_Resources | SA_FSAA_Resources_Enum_IDX | Nonclustered | No | HOST, ParentResourceID; INCLUDE ID, ResourceType, DeletedUSN | +| SA_FSAA_Resources | SA_FSAA_Resources_RightsProxyID_IDX | Nonclustered | No | HOST, RightsProxyID; INCLUDE ID, GatesProxyID, DeletedUSN, ResourceType | +| SA_FSAA_Resources | SA_FSAA_Resources_GatesProxyID_IDX | Nonclustered | No | HOST, GatesProxyID; INCLUDE ID | +| SA_FSAA_Resources | SA_FSAA_Resources_USN_IDX | Nonclustered | No | HOST, USN; INCLUDE ID | +| SA_FSAA_Resources | SA_FSAA_Resources_ParentResourceID_Name_IDX | Nonclustered | No | HOST, ParentResourceID, Name | +| SA_FSAA_UnixRights | PK_SA_FSAA_UnixRights | Clustered | Yes | HOST, ResourceID | +| SA_FSAA_Gates | PK_SA_FSAA_Gates | Clustered | Yes | HOST, ID | +| SA_FSAA_GatesProxy | PK_SA_FSAA_GatesProxy | Clustered | Yes | HOST, ID, GateID | +| SA_FSAA_GatesProxy | SA_FSAA_GatesProxy_GateID_IDX | Nonclustered | No | HOST, GateID; INCLUDE ID | +| SA_FSAA_Policies | PK_SA_FSAA_Policies | Clustered | Yes | HOST, PolicyID, TrusteeID | +| SA_FSAA_Exceptions | PK_SA_FSAA_Exceptions | Clustered | Yes | HOST, ID | +| SA_FSAA_Exceptions | SA_FSAA_Exceptions_Resource_IDX | Nonclustered | No | HOST, ResourceID; INCLUDE ExceptionType, GateID | +| SA_FSAA_ExceptionTypes | PK_SA_FSAA_ExceptionTypes | Clustered | Yes | HOST, ExceptionType | +| SA_FSAA_ProbableOwners | PK_SA_FSAA_ProbableOwners | Clustered | Yes | HOST, ResourceID, OwnerID | +| SA_FSAA_FileSizes | PK_SA_FSAA_FileSizes | Clustered | Yes | HOST, ResourceID | +| SA_FSAA_FileTypes | PK_SA_FSAA_FileTypes | Clustered | Yes | HOST, ResourceID, Extension | +| SA_FSAA_FileAges | PK_SA_FSAA_FileAges | Clustered | Yes | HOST, ResourceID | +| SA_FSAA_FileTags | PK_SA_FSAA_FileTags | Clustered | Yes | HOST, ResourceID, TagProxyID | +| SA_FSAA_AzureFilesShares | PK_SA_FSAA_AzureFilesShares | Clustered | Yes | HOST, ID | +| SA_FSAA_AzureFilesShareProperties | PK_SA_FSAA_AzureFilesShareProperties | Clustered | Yes | HOST, AzureShareID | +| SA_FSAA_TrusteeMap | PK_SA_FSAA_TrusteeMap | Clustered | Yes | HOST, ID | +| SA_FSAA_ResourceMap | PK_SA_FSAA_ResourceMap | Clustered | Yes | HOST, ID | +| SA_FSAA_ResourceMap | SA_FSAA_ResourceMap_AccessID_IDX | Nonclustered | No | HOST, AccessID | +| SA_FSAA_ResourceMap | SA_FSAA_ResourceMap_ActivityID_IDX | Nonclustered | No | HOST, ActivityID | +| SA_FSAA_ResourceMap | SA_FSAA_ResourceMap_DLPID_IDX | Nonclustered | No | HOST, DLPID | +| SA_FSAA_GateMap | PK_SA_FSAA_GateMap | Clustered | Yes | HOST, ID | +| SA_FSAA_ResourcesScanTypeDetails | PK_SA_FSAA_ResourcesScanTypeDetails | Clustered | Yes | HOST, ID | +| SA_FSAC_ProcessNames | PK_SA_FSAC_ProcessNames | Clustered | Yes | HOST, ID | +| SA_FSAC_ActivityEvents | PK_SA_FSAC_ActivityEvents | Clustered | Yes | HOST, ID | +| SA_FSAC_ActivityEvents | SA_FSAC_ActivityEvents_PathID_IDX | Nonclustered | No | HOST, PathID; INCLUDE ID, AccessTime, TrusteeID, Operation, Allow | +| SA_FSAC_ActivityEvents | SA_FSAC_ActivityEvents_TrusteeID_IDX | Nonclustered | No | TrusteeID, AccessTime; INCLUDE PathID, ProcessID, Operation, Allow | +| SA_FSAC_PermissionChanges | PK_SA_FSAC_PermissionChanges | Clustered | Yes | HOST, ActivityID, ChangeID | +| SA_FSAC_DailyActivity | PK_SA_FSAC_DailyActivity | Clustered | Yes | HOST, FolderID, ActivityDate, TrusteeID, Operation, Allow | +| SA_FSAC_OwnerChanges | PK_SA_FSAC_OwnerChanges | Clustered | Yes | HOST, ActivityID | +| SA_FSAC_RenameTargets | PK_SA_FSAC_RenameTargets | Clustered | Yes | HOST, ActivityID | +| SA_FSAC_ExceptionTypes | PK_SA_FSAC_ExceptionTypes | Clustered | Yes | HOST, ExceptionType | +| SA_FSAC_Exceptions | PK_SA_FSAC_Exceptions | Clustered | Yes | HOST, ID | +| SA_FSAC_Exceptions | SA_FSAC_Exceptions_ResourceID_IDX | Nonclustered | No | HOST, ResourceID; INCLUDE GateID | +| SA_FSAC_UserExceptionTypes | PK_SA_FSAC_UserExceptionTypes | Clustered | Yes | SID, ExceptionType | +| SA_FSAC_UserExceptions | PK_SA_FSAC_UserExceptions | Clustered | Yes | ID | +| SA_FSDLP_ImportHistory | PK_SA_FSDLP_ImportHistory | Clustered | Yes | HOST, USN | +| SA_FSDLP_Criteria | PK_SA_FSDLP_Criteria | Clustered | Yes | HOST, ID | +| SA_FSDLP_Matches | PK_SA_FSDLP_Matches | Clustered | Yes | HOST, FileId, CriteriaId | +| SA_FSDLP_MatchHits | PK_SA_FSDLP_MatchHits | Clustered | Yes | HOST, FileId, CriteriaId, ID | +| SA_FSDLP_MatchHits_SubjectProfile | PK_SA_FSDLP_MatchHits_SubjectProfile | Clustered | Yes | HOST, FileId, CriteriaId, ID | +| SA_FSDFS_Namespaces | PK_SA_FSDFS_Namespaces | Clustered | Yes | ID | +| SA_FSDFS_Links | PK_SA_FSDFS_Links | Clustered | Yes | HOST, ID | +| SA_FSDFS_Links | UQ_FSDFS_Links_DfsPath | Nonclustered | Yes | DfsPath, NamespaceID | +| SA_FSDFS_Links | SA_FSDFS_Links_GateID_IDX | Nonclustered | No | TargetHostID, TargetGateID | + +The following tables carry no indexes at all (no clustered PK and no nonclustered indexes): + +- `SA_FSAA_SchemaVer` +- `SA_FSAA_ScanHistory` +- `SA_FSAA_AzureStorageAccounts` diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/overview.md new file mode 100644 index 0000000000..f882f66120 --- /dev/null +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/overview.md @@ -0,0 +1,111 @@ +# File System Access Analyzer Data Collector Schema + +The File System Access Analyzer (FSAA) data collector audits Windows, NFS, and Azure Files file systems for permissions, ownership, content, activity, and sensitive-data classification. FSAA scans Windows servers, NetApp/EMC/Dell filers, Linux/Unix hosts, and Azure Files shares; normalizes the security model into a unified per-host identity space; and writes the results to the central Access Analyzer database. Every core data table is partitioned by host, so removing a host atomically purges its entire collected data set across all four collector modules. + +### [Table Relationship Diagrams (ERD)](erd/overview.md) + +- [Top-level partitioning — every table hangs off SA_FSAA_Hosts](erd/overview.md#top-level-partitioning) +- [Trustees — security-principal identity model](erd/overview.md#trustees) +- [Resources & content aggregations](erd/overview.md#resources) +- [Gates and permissions](erd/overview.md#gates-and-permissions) +- [Tags](erd/overview.md#tags) +- [Exceptions](erd/overview.md#exceptions) +- [Azure Files](erd/overview.md#azure-files) +- [Activity collection (SA_FSAC_*)](erd/overview.md#activity-collection) +- [Sensitive data — DLP (SA_FSDLP_*)](erd/overview.md#sensitive-data) +- [DFS namespaces (SA_FSDFS_*)](erd/overview.md#dfs-namespaces) + +### [Core Data Collection Tables](coretables/overview.md) + +- [SA_FSAA_SchemaVer](coretables/overview.md#sa_fsaa_schemaver) +- [SA_FSAA_Hosts](coretables/overview.md#sa_fsaa_hosts) +- [SA_FSAA_ImportHistory](coretables/overview.md#sa_fsaa_importhistory) +- [SA_FSAA_Trustees](coretables/overview.md#sa_fsaa_trustees) +- [SA_FSAA_LocalTrustees](coretables/overview.md#sa_fsaa_localtrustees) +- [SA_FSAA_TrusteeEquivalence](coretables/overview.md#sa_fsaa_trusteeequivalence) +- [SA_FSAA_Rights](coretables/overview.md#sa_fsaa_rights) +- [SA_FSAA_Tags](coretables/overview.md#sa_fsaa_tags) +- [SA_FSAA_TagKeys](coretables/overview.md#sa_fsaa_tagkeys) +- [SA_FSAA_TagProxies](coretables/overview.md#sa_fsaa_tagproxies) +- [SA_FSAA_Resources](coretables/overview.md#sa_fsaa_resources) +- [SA_FSAA_UnixRights](coretables/overview.md#sa_fsaa_unixrights) +- [SA_FSAA_Gates](coretables/overview.md#sa_fsaa_gates) +- [SA_FSAA_GatesProxy](coretables/overview.md#sa_fsaa_gatesproxy) +- [SA_FSAA_Policies](coretables/overview.md#sa_fsaa_policies) +- [SA_FSAA_Exceptions](coretables/overview.md#sa_fsaa_exceptions) +- [SA_FSAA_ExceptionTypes](coretables/overview.md#sa_fsaa_exceptiontypes) +- [SA_FSAA_ProbableOwners](coretables/overview.md#sa_fsaa_probableowners) +- [SA_FSAA_FileSizes](coretables/overview.md#sa_fsaa_filesizes) +- [SA_FSAA_FileTypes](coretables/overview.md#sa_fsaa_filetypes) +- [SA_FSAA_FileAges](coretables/overview.md#sa_fsaa_fileages) +- [SA_FSAA_FileTags](coretables/overview.md#sa_fsaa_filetags) +- [SA_FSAA_ScanHistory](coretables/overview.md#sa_fsaa_scanhistory) +- [SA_FSAA_AzureFilesShares](coretables/overview.md#sa_fsaa_azurefilesshares) +- [SA_FSAA_AzureFilesShareProperties](coretables/overview.md#sa_fsaa_azurefilesshareproperties) +- [SA_FSAA_AzureStorageAccounts](coretables/overview.md#sa_fsaa_azurestorageaccounts) +- [SA_FSAA_TrusteeMap](coretables/overview.md#sa_fsaa_trusteemap) +- [SA_FSAA_ResourceMap](coretables/overview.md#sa_fsaa_resourcemap) +- [SA_FSAA_GateMap](coretables/overview.md#sa_fsaa_gatemap) +- [SA_FSAA_ResourcesScanTypeDetails](coretables/overview.md#sa_fsaa_resourcesscantypedetails) +- [SA_FSAC_ProcessNames](coretables/overview.md#sa_fsac_processnames) +- [SA_FSAC_ActivityEvents](coretables/overview.md#sa_fsac_activityevents) +- [SA_FSAC_PermissionChanges](coretables/overview.md#sa_fsac_permissionchanges) +- [SA_FSAC_OwnerChanges](coretables/overview.md#sa_fsac_ownerchanges) +- [SA_FSAC_DailyActivity](coretables/overview.md#sa_fsac_dailyactivity) +- [SA_FSAC_RenameTargets](coretables/overview.md#sa_fsac_renametargets) +- [SA_FSAC_ExceptionTypes](coretables/overview.md#sa_fsac_exceptiontypes) +- [SA_FSAC_Exceptions](coretables/overview.md#sa_fsac_exceptions) +- [SA_FSAC_UserExceptionTypes](coretables/overview.md#sa_fsac_userexceptiontypes) +- [SA_FSAC_UserExceptions](coretables/overview.md#sa_fsac_userexceptions) +- [SA_FSDLP_ImportHistory](coretables/overview.md#sa_fsdlp_importhistory) +- [SA_FSDLP_Criteria](coretables/overview.md#sa_fsdlp_criteria) +- [SA_FSDLP_Matches](coretables/overview.md#sa_fsdlp_matches) +- [SA_FSDLP_MatchHits](coretables/overview.md#sa_fsdlp_matchhits) +- [SA_FSDLP_MatchHits_SubjectProfile](coretables/overview.md#sa_fsdlp_matchhits_subjectprofile) +- [SA_FSDFS_Namespaces](coretables/overview.md#sa_fsdfs_namespaces) +- [SA_FSDFS_Links](coretables/overview.md#sa_fsdfs_links) + +### [Views](views/overview.md) + +- [SA_FSAA_Paths](views/overview.md#sa_fsaa_paths) +- [SA_FSAA_ResourcesView](views/overview.md#sa_fsaa_resourcesview) +- [SA_FSAA_PermissionsView](views/overview.md#sa_fsaa_permissionsview) +- [SA_FSAA_ExpandedPermissionsView](views/overview.md#sa_fsaa_expandedpermissionsview) +- [SA_FSAA_DirectPermissionsView](views/overview.md#sa_fsaa_directpermissionsview) +- [SA_FSAA_InheritedPermissionsView](views/overview.md#sa_fsaa_inheritedpermissionsview) +- [SA_FSAA_SharesTraversalView](views/overview.md#sa_fsaa_sharestraversalview) +- [SA_FSAA_EffectiveAccessView](views/overview.md#sa_fsaa_effectiveaccessview) +- [SA_FSAA_LocalGroupMembersView](views/overview.md#sa_fsaa_localgroupmembersview) +- [SA_FSAA_ExceptionsView](views/overview.md#sa_fsaa_exceptionsview) +- [SA_FSAA_AzureFilesPermissionsView](views/overview.md#sa_fsaa_azurefilespermissionsview) +- [SA_FSAC_DailyActivityView](views/overview.md#sa_fsac_dailyactivityview) +- [SA_FSAC_DailyUserActivityView](views/overview.md#sa_fsac_dailyuseractivityview) +- [SA_FSAC_DailyResourceActivityView](views/overview.md#sa_fsac_dailyresourceactivityview) +- [SA_FSAC_ActivityEventsView](views/overview.md#sa_fsac_activityeventsview) +- [SA_FSAC_ExceptionsView](views/overview.md#sa_fsac_exceptionsview) +- [SA_FSAC_UserExceptionsView](views/overview.md#sa_fsac_userexceptionsview) +- [SA_FSAC_PermissionChangesView](views/overview.md#sa_fsac_permissionchangesview) +- [SA_FSDLP_MatchesView](views/overview.md#sa_fsdlp_matchesview) +- [SA_FSDLP_MatchHitsView](views/overview.md#sa_fsdlp_matchhitsview) + +### [Enumeration & Lookup Values](enumeration/overview.md) + +- [TrusteeType](enumeration/overview.md#trusteetype) +- [ResourceType](enumeration/overview.md#resourcetype) +- [GateType](enumeration/overview.md#gatetype) +- [Rights Bitmask — AllowRights / DenyRights](enumeration/overview.md#rights-bitmask) + +### [Functions & Stored Procedures](functions/overview.md) + +- [FSAA Functions (SA_FSAA_*)](functions/overview.md#fsaa-functions) +- [Activity Collector Functions (SA_FSAC_*)](functions/overview.md#activity-collector-functions) +- [DFS Functions (SA_FSDFS_*)](functions/overview.md#dfs-functions) +- [Shared Core Functions (SA_CORE_*)](functions/overview.md#shared-core-functions) + +### [Index Reference](indexreference/overview.md) + +- [Complete Index Listing](indexreference/overview.md#complete-index-listing) + +### [Foreign Key Reference](fkreference/overview.md) + +- [Complete Foreign Key Listing](fkreference/overview.md#complete-foreign-key-listing) diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/views/_category_.json b/docs/accessanalyzer/12.0/admin/schema/fsaadc/views/_category_.json new file mode 100644 index 0000000000..2c72e59702 --- /dev/null +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/views/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Views", + "position": 30, + "collapsed": true, + "collapsible": true, + "link": { + "type": "doc", + "id": "overview" + } +} diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/views/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/views/overview.md new file mode 100644 index 0000000000..fc560da722 --- /dev/null +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/views/overview.md @@ -0,0 +1,551 @@ +# Views + +The FSAA DC schema exposes 20 views that provide pre-joined, human-readable projections of the underlying tables. Reports and the Access Analyzer web UI consume these views rather than raw tables. + +:::note +Column sizes shown for views are derived from underlying source columns and SQL `CASE` expressions in the view definitions; on a populated database the actual `sys.columns.max_length` may differ slightly. Use `EXEC sp_help ''` to inspect a view's exact runtime shape. +::: + +## FSAA Views + +### SA_FSAA_Paths {#sa_fsaa_paths} + +Path map for every resource. Implemented as a VIEW (not a table) — the Create-Schema job explicitly drops any pre-existing table form before executing `CREATE VIEW`. The view delegates path construction to the `SA_FSAA_GetPath` scalar UDF, which walks the parent chain recursively. + +**Source:** `SA_FSAA_Resources` (via `SA_FSAA_GetPath` UDF — recursive parent-chain walk) + +| Column | Type | Source | Description | +|---|---|---|---| +| HOST | int | SA_FSAA_Resources.HOST | Host partition | +| ResourceID | bigint | SA_FSAA_Resources.ID | Resource | +| Path | nvarchar(4000) | Computed (recursive concat of `SA_FSAA_Resources.Name` up the parent chain) | Full path string | + +### SA_FSAA_ResourcesView {#sa_fsaa_resourcesview} + +Surface view of `SA_FSAA_Resources` enriched with computed full path, resource-type description, three boolean permission flags (`PermissionChange`, `InheritedPermission`, `DirectPermission`), and Azure Files metadata. Two definitions exist; the Entra-aware variant is used when `SA_Entra_RmResources` exists. + +**Source tables:** `SA_FSAA_Resources`, `SA_FSAA_Hosts`, `SA_FSAA_Rights`, `SA_FSAA_AzureFilesShares`, `SA_Entra_RmResources` (when present) + +| Column | Type | Source | Description | +|---|---|---|---| +| HostID | int | SA_FSAA_Resources.HOST | Host ID | +| HostName | nvarchar(64) | SA_FSAA_Hosts.HOST | Host name | +| ID | bigint | SA_FSAA_Resources.ID | Resource ID | +| ParentResourceID | bigint | SA_FSAA_Resources.ParentResourceID | Parent resource | +| Name | nvarchar(2000) | SA_FSAA_Resources.Name | Leaf name | +| Path | nvarchar(4000) | UDF: SA_FSAA_GetPath | Full path | +| ResourceType | tinyint | SA_FSAA_Resources.ResourceType | See [ResourceType](../enumeration/overview.md#resourcetype) | +| ResourceTypeDescription | varchar(6) | Computed (CASE) | `Share`, `Folder`, or `File` | +| OwnerID | int | SA_FSAA_Resources.OwnerID | | +| RightsProxyID | int | SA_FSAA_Resources.RightsProxyID | | +| GatesProxyID | bigint | SA_FSAA_Resources.GatesProxyID | | +| NestedLevel | int | SA_FSAA_Resources.NestedLevel | | +| Size | bigint | SA_FSAA_Resources.Size | | +| LastModified | datetime | SA_FSAA_Resources.LastModified | | +| LastAccessed | datetime | SA_FSAA_Resources.LastAccessed | | +| Created | datetime | SA_FSAA_Resources.Created | | +| USN | int | SA_FSAA_Resources.USN | | +| DeletedUSN | int | SA_FSAA_Resources.DeletedUSN | | +| PermissionChange | bit | Computed (CASE / EXISTS) | True if ACL differs from parent | +| InheritedPermission | bit | Computed (CASE / EXISTS) | True if any inherited rights exist | +| DirectPermission | bit | Computed (CASE / EXISTS) | True if any direct rights exist | +| Storage Account | varchar(256) | SA_FSAA_AzureFilesShares.StorageAccount | Entra-aware variant only | +| Azure File Share Name | nvarchar(2000) | SA_FSAA_AzureFilesShares.Name | Entra-aware variant only | +| Azure TenantID | varchar(38) | SA_Entra_RmResources.DomainId | Entra-aware variant only | + +### SA_FSAA_PermissionsView {#sa_fsaa_permissionsview} + +Resource × ACE flat view with effective allow/deny rights expanded into 12 boolean columns, textual `AllowRightsDescription`/`DenyRightsDescription` (e.g. `LRWDMA`), and a `RightsSource` column (`Direct` / `Inherited` / `Both` / `None`). + +**Source tables:** `SA_FSAA_Resources`, `SA_FSAA_Hosts`, `SA_FSAA_Rights`, `SA_FSAA_Trustees`, UDF `SA_FSAA_GetTrusteeInformationEx` +**Filter:** `r.RightsProxyID IS NOT NULL` + +| Column | Type | Source | Description | +|---|---|---|---| +| HostID | int | SA_FSAA_Resources.HOST | Host partition | +| HostName | nvarchar(64) | SA_FSAA_Hosts.HOST | Host name | +| ResourceID | bigint | SA_FSAA_Resources.ID | Resource | +| ParentResourceID | bigint | SA_FSAA_Resources.ParentResourceID | Parent resource | +| ResourceDeletedUSN | int | SA_FSAA_Resources.DeletedUSN | NULL if not deleted | +| ResourcePath | nvarchar(4000) | UDF: SA_FSAA_GetPath | Full resource path | +| ResourceType | tinyint | SA_FSAA_Resources.ResourceType | | +| ResourceTypeDescription | varchar(6) | Computed (CASE) | `Share` / `Folder` / `File` | +| AllowRights | smallint | SA_FSAA_Rights.AllowRights | Combined bitmask | +| DenyRights | smallint | SA_FSAA_Rights.DenyRights | Combined bitmask | +| AllowList | bit | Computed (`AllowRights & 32`) | Has list right | +| AllowRead | bit | Computed (`AllowRights & 1`) | Has read right | +| AllowWrite | bit | Computed (`AllowRights & 2`) | Has write right | +| AllowDelete | bit | Computed (`AllowRights & 4`) | Has delete right | +| AllowManage | bit | Computed (`AllowRights & 8`) | Has manage right | +| AllowAdmin | bit | Computed (`AllowRights & 16`) | Has admin right | +| DenyList | bit | Computed (`DenyRights & 32`) | Deny list right | +| DenyRead | bit | Computed (`DenyRights & 1`) | Deny read right | +| DenyWrite | bit | Computed (`DenyRights & 2`) | Deny write right | +| DenyDelete | bit | Computed (`DenyRights & 4`) | Deny delete right | +| DenyManage | bit | Computed (`DenyRights & 8`) | Deny manage right | +| DenyAdmin | bit | Computed (`DenyRights & 16`) | Deny admin right | +| AllowRightsDescription | varchar(6) | Computed (concat letters L/R/W/D/M/A) | e.g. `LRW` | +| DenyRightsDescription | varchar(6) | Computed (concat letters L/R/W/D/M/A) | e.g. `D` | +| RightsSource | varchar(9) | Computed (CASE on Direct/Inherited columns) | `Both` / `Inherited` / `Direct` / `None` | +| AllowMask | int | SA_FSAA_Rights.AllowMask | Full Windows access mask | +| DenyMask | int | SA_FSAA_Rights.DenyMask | Full Windows deny mask | +| AllowMaskDescription | varchar(32) | Computed (CASE) | `Full Control` / `Modify` / `Read & Execute` / etc. | +| DenyMaskDescription | varchar(32) | Computed (CASE) | Same vocabulary as AllowMaskDescription | +| TrusteeID | int | SA_FSAA_Rights.TrusteeID | | +| TrusteeSID | varchar(184) | SA_FSAA_Trustees.SID | | +| TrusteeType | smallint | UDF column | See [TrusteeType](../enumeration/overview.md#trusteetype) | +| TrusteeIsHistoricalSID | bit | UDF column | True if SID came from SID History | +| TrusteePrincipalID | int | UDF column | AD-Inventory principal ID | +| TrusteeTypeDescription | varchar(18) | Computed (CASE) | e.g. `Domain User` | +| TrusteeDisplayName | nvarchar(256) | UDF column | | +| TrusteeDomain | nvarchar(128) | UDF column | NT domain | +| TrusteeNTName | nvarchar(256) | UDF column | SAM account name | +| TrusteeNTStyleName | nvarchar(385) | Computed (`Domain\Name`) | Concatenated NT-style name | + +### SA_FSAA_ExpandedPermissionsView {#sa_fsaa_expandedpermissionsview} + +Resource × *expanded* effective trustee — group memberships are recursively expanded and the view returns one row per `(resource, leaf trustee)` instead of one per `(resource, ACE)`. Uses `CROSS APPLY dbo.SA_FSAA_GetExpandedPermissions` to do the expansion. + +**Source tables:** `SA_FSAA_Resources`, `SA_FSAA_Hosts`, UDF `SA_FSAA_GetExpandedPermissions` +**Filter:** `r.RightsProxyID IS NOT NULL` + +| Column | Type | Source | Description | +|---|---|---|---| +| HostID | int | SA_FSAA_Resources.HOST | Host partition | +| HostName | nvarchar(64) | SA_FSAA_Hosts.HOST | Host name | +| ResourceID | bigint | SA_FSAA_Resources.ID | Resource | +| ParentResourceID | bigint | SA_FSAA_Resources.ParentResourceID | Parent resource | +| ResourceDeletedUSN | int | SA_FSAA_Resources.DeletedUSN | | +| ResourcePath | nvarchar(4000) | UDF: SA_FSAA_GetPath | Full path | +| ResourceType | tinyint | SA_FSAA_Resources.ResourceType | | +| ResourceTypeDescription | varchar(6) | Computed (CASE) | `Share` / `Folder` / `File` | +| AllowRights | smallint | UDF column | Effective allow bitmask after group expansion | +| DenyRights | smallint | UDF column | Effective deny bitmask | +| AllowList / AllowRead / AllowWrite / AllowDelete / AllowManage / AllowAdmin | bit | Computed (`AllowRights & N`) | Six boolean columns (bits 32, 1, 2, 4, 8, 16) | +| DenyList / DenyRead / DenyWrite / DenyDelete / DenyManage / DenyAdmin | bit | Computed (`DenyRights & N`) | Six boolean columns | +| AllowRightsDescription | varchar(6) | Computed | Letter form `LRWDMA` | +| DenyRightsDescription | varchar(6) | Computed | | +| TrusteeSID | varchar(184) | UDF column | Leaf-trustee SID | +| TrusteeType | smallint | UDF column | See [TrusteeType](../enumeration/overview.md#trusteetype) | +| TrusteeTypeDescription | varchar(18) | Computed (CASE) | | +| TrusteeDisplayName | nvarchar(256) | UDF column | | +| TrusteeDomain | nvarchar(128) | UDF column | | +| TrusteeNTName | nvarchar(256) | UDF column | | +| TrusteeNTStyleName | nvarchar(385) | Computed (`Domain\Name`) | | + +### SA_FSAA_DirectPermissionsView {#sa_fsaa_directpermissionsview} + +Same shape as `SA_FSAA_PermissionsView` but filtered to direct (non-inherited) ACEs only. Uses `DirectAllowRights` / `DirectDenyRights` / `DirectAllowMask` / `DirectDenyMask` as the source columns; the output column names remain `AllowRights`, `DenyRights`, `AllowMask`, `DenyMask`. + +**Source tables:** `SA_FSAA_Resources`, `SA_FSAA_Hosts`, `SA_FSAA_Rights`, `SA_FSAA_Trustees`, UDF `SA_FSAA_GetTrusteeInformationEx` +**Filter:** `r.RightsProxyID IS NOT NULL AND ((p.DirectAllowRights <> 0) OR (p.DirectDenyRights <> 0) OR (p.DirectAllowMask <> 0) OR (p.DirectDenyMask <> 0))` + +Column shape is identical to `SA_FSAA_PermissionsView`. Source columns changed: `AllowRights` ← `DirectAllowRights`, `DenyRights` ← `DirectDenyRights`, `AllowMask` ← `DirectAllowMask`, `DenyMask` ← `DirectDenyMask`. + +### SA_FSAA_InheritedPermissionsView {#sa_fsaa_inheritedpermissionsview} + +Same shape as `SA_FSAA_DirectPermissionsView` but reads from the `Inherited*` rights/mask columns. + +**Source tables:** `SA_FSAA_Resources`, `SA_FSAA_Hosts`, `SA_FSAA_Rights`, `SA_FSAA_Trustees`, UDF `SA_FSAA_GetTrusteeInformationEx` +**Filter:** `r.RightsProxyID IS NOT NULL AND ((p.InheritedAllowRights <> 0) OR (p.InheritedDenyRights <> 0) OR (p.InheritedAllowMask <> 0) OR (p.InheritedDenyMask <> 0))` + +Column shape is identical to `SA_FSAA_PermissionsView`. Source columns changed: `AllowRights` ← `InheritedAllowRights`, `DenyRights` ← `InheritedDenyRights`, `AllowMask` ← `InheritedAllowMask`, `DenyMask` ← `InheritedDenyMask`. + +### SA_FSAA_SharesTraversalView {#sa_fsaa_sharestraversalview} + +For every resource reachable through a gate, returns the gate, the resource, the share-relative resource path, and the SMB/NFS/Azure UNC path. Two definitions exist; the Entra-aware variant adds storage-account/tenant/share-property columns when `SA_Entra_RmResources` is present. + +**Source tables:** `SA_FSAA_Hosts`, `SA_FSAA_Gates`, `SA_FSAA_GatesProxy`, `SA_FSAA_Resources`, `SA_FSAA_Paths`, plus (Entra-aware) `SA_FSAA_AzureFilesShares`, `SA_FSAA_AzureFilesShareProperties`, `SA_Entra_RmResources` +**Filter:** `r.GatesProxyID IS NOT NULL` + +| Column | Type | Source | Description | +|---|---|---|---| +| HostID | int | SA_FSAA_Hosts.ID | | +| HostName | nvarchar(64) | SA_FSAA_Hosts.HOST | | +| GateID | int | SA_FSAA_Gates.ID | | +| GateType | int | SA_FSAA_Gates.GateType | See [GateType](../enumeration/overview.md#gatetype) | +| GateTypeDescription | varchar(3) | Computed (CASE) | `SMB` or `NFS` | +| GateDeletedUSN | int | SA_FSAA_Gates.DeletedUSN | | +| ShareID | bigint | SA_FSAA_Gates.ShareID | | +| ShareName | nvarchar(256) | SA_FSAA_Gates.DisplayName | | +| ResourceID | bigint | SA_FSAA_Resources.ID | | +| ParentResourceID | bigint | SA_FSAA_Resources.ParentResourceID | | +| ResourceType | tinyint | SA_FSAA_Resources.ResourceType | | +| ResourceTypeDescription | varchar(6) | Computed (CASE) | | +| ResourceDeletedUSN | int | SA_FSAA_Resources.DeletedUSN | | +| ResourcePath | nvarchar(4000) | SA_FSAA_Paths.Path | Local resource path | +| NetworkPath | nvarchar(4000) | Computed | UNC path or NFS-style path (`host:share//rel-path` for NFS; `\\host\share\rel-path` for SMB) | +| NestedLevel | int | Computed (`r.NestedLevel - g.NestedLevel`) | Depth from share root | +| Storage Account | varchar(256) | SA_FSAA_AzureFilesShares.StorageAccount | Entra-aware variant only | +| Azure File Share Name | nvarchar(2000) | SA_FSAA_AzureFilesShares.Name | Entra-aware variant only | +| Azure TenantID | varchar(38) | SA_Entra_RmResources.DomainId | Entra-aware variant only | +| AzureShareID | int | SA_FSAA_AzureFilesShareProperties.AzureShareID | Entra-aware variant only | +| AccessChangeTime | datetime2(7) | SA_FSAA_AzureFilesShareProperties.AccessChangeTime | Entra-aware variant only | +| DeletedOn | datetime2(7) | SA_FSAA_AzureFilesShareProperties.DeletedOn | Entra-aware variant only | +| LastModified | datetime2(7) | SA_FSAA_AzureFilesShareProperties.LastModified | Entra-aware variant only | +| LeaseDuration | varchar(50) | SA_FSAA_AzureFilesShareProperties.LeaseDuration | Entra-aware variant only | +| QuotaInGB | float | SA_FSAA_AzureFilesShareProperties.QuotaInGB | Entra-aware variant only | +| RemainingRetentionDays | int | SA_FSAA_AzureFilesShareProperties.RemainingRetentionDays | Entra-aware variant only | + +### SA_FSAA_EffectiveAccessView {#sa_fsaa_effectiveaccessview} + +Like `SA_FSAA_SharesTraversalView` but additionally resolves each row through `SA_FSAA_GetEffectiveRights` to attribute effective allow/deny rights to each leaf trustee. Used to answer "who can do what on this resource through this share?" + +**Source tables:** `SA_FSAA_SharesTraversalView`, UDF `SA_FSAA_GetEffectiveRights` + +| Column | Type | Source | Description | +|---|---|---|---| +| HostID | int | SA_FSAA_SharesTraversalView.HostID | | +| HostName | nvarchar(64) | SA_FSAA_SharesTraversalView.HostName | | +| GateID | int | SA_FSAA_SharesTraversalView.GateID | | +| ShareID | bigint | SA_FSAA_SharesTraversalView.ShareID | | +| ResourceID | bigint | SA_FSAA_SharesTraversalView.ResourceID | | +| ShareName | nvarchar(256) | SA_FSAA_SharesTraversalView.ShareName | | +| NestedLevel | int | SA_FSAA_SharesTraversalView.NestedLevel | | +| ResourcePath | nvarchar(4000) | SA_FSAA_SharesTraversalView.ResourcePath | | +| NetworkPath | nvarchar(4000) | SA_FSAA_SharesTraversalView.NetworkPath | | +| ResourceType | tinyint | SA_FSAA_SharesTraversalView.ResourceType | | +| ResourceTypeDescription | varchar(6) | SA_FSAA_SharesTraversalView.ResourceTypeDescription | | +| ResourceDeletedUSN | int | SA_FSAA_SharesTraversalView.ResourceDeletedUSN | | +| GateDeletedUSN | int | SA_FSAA_SharesTraversalView.GateDeletedUSN | | +| AllowRights | smallint | UDF column | Effective allow bitmask | +| DenyRights | smallint | UDF column | Effective deny bitmask | +| DirectTrustee | bit | UDF column | True if rights come from a direct ACE rather than group expansion | +| AllowList / AllowRead / AllowWrite / AllowDelete / AllowManage / AllowAdmin | bit | Computed | Six boolean columns | +| DenyList / DenyRead / DenyWrite / DenyDelete / DenyManage / DenyAdmin | bit | Computed | Six boolean columns | +| AllowRightsDescription | varchar(6) | Computed | | +| DenyRightsDescription | varchar(6) | Computed | | +| TrusteeSID | varchar(184) | UDF column | | +| TrusteeType | smallint | UDF column | | +| TrusteeTypeDescription | varchar(18) | Computed (CASE) | | +| TrusteeDisplayName | nvarchar(256) | UDF column | | +| TrusteeDomain | nvarchar(128) | UDF column | | +| TrusteeNTName | nvarchar(256) | UDF column | | +| TrusteeNTStyleName | nvarchar(385) | Computed | | + +### SA_FSAA_LocalGroupMembersView {#sa_fsaa_localgroupmembersview} + +Flat view of local-group memberships derived from `SA_FSAA_TrusteeEquivalence`. One row per `(group, member)` pair on a host, with both group and member identity columns expanded via `SA_FSAA_GetTrusteeInformation`. + +**Source tables:** `SA_FSAA_TrusteeEquivalence`, `SA_FSAA_Hosts`, UDF `SA_FSAA_GetTrusteeInformation` (called twice — once for the group, once for the member) + +| Column | Type | Source | Description | +|---|---|---|---| +| HostID | int | SA_FSAA_TrusteeEquivalence.HOST | | +| HostName | nvarchar(64) | SA_FSAA_Hosts.HOST | | +| GroupTrusteeID | int | SA_FSAA_TrusteeEquivalence.EquivalentTrusteeID | | +| GroupSID | varchar(184) | UDF column (group) | | +| GroupDisplayName | nvarchar(256) | UDF column (group) | | +| GroupDomain | nvarchar(128) | UDF column (group) | | +| GroupNTName | nvarchar(256) | UDF column (group) | | +| GroupNTStyleName | nvarchar(385) | Computed (`Domain\Name`) | | +| MemberTrusteeID | int | SA_FSAA_TrusteeEquivalence.TrusteeID | | +| MemberSID | varchar(184) | UDF column (member) | | +| MemberDomain | nvarchar(128) | UDF column (member) | | +| MemberNTName | nvarchar(256) | UDF column (member) | | +| MemberDisplayName | nvarchar(256) | UDF column (member) | | +| MemberNTStyleName | nvarchar(385) | Computed (`Domain\Name`) | | +| MemberType | smallint | UDF column (member) | See [TrusteeType](../enumeration/overview.md#trusteetype) | +| MemberTypeDescription | varchar(18) | Computed (CASE) | | +| MemberPrincipalID | int | UDF column (member) | AD-Inventory principal ID | + +### SA_FSAA_ExceptionsView {#sa_fsaa_exceptionsview} + +`SA_FSAA_Exceptions` joined with the type catalog and with both `TrusteeID` and `SourceTrusteeID` resolved to display names. + +**Source tables:** `SA_FSAA_Exceptions`, `SA_FSAA_ExceptionTypes`, `SA_FSAA_Trustees` (twice), `SA_FSAA_Hosts`, `SA_FSAA_Resources`, `SA_FSAA_Gates`, UDF `SA_FSAA_GetTrusteeInformationEx` + +| Column | Type | Source | Description | +|---|---|---|---| +| HostID | int | SA_FSAA_Exceptions.HOST | | +| HostName | nvarchar(64) | SA_FSAA_Hosts.HOST | | +| ExceptionType | int | SA_FSAA_Exceptions.ExceptionType | | +| ParentType | int | SA_FSAA_ExceptionTypes.ParentType | Hierarchical parent type | +| ExceptionName | varchar(128) | SA_FSAA_ExceptionTypes.Name | | +| GateID | int | SA_FSAA_Exceptions.GateID | | +| ResourceID | bigint | SA_FSAA_Exceptions.ResourceID | | +| Path | nvarchar(4000) | Computed | UNC path / resource path / NULL depending on which columns are populated | +| TrusteeID | int | SA_FSAA_Exceptions.TrusteeID | | +| TrusteeSID | varchar(184) | SA_FSAA_Trustees.SID | | +| TrusteeType | smallint | SA_FSAA_Trustees.TrusteeType | | +| TrusteeDisplayName | nvarchar(256) | UDF column | | +| TrusteeNTStyleName | nvarchar(385) | Computed | | +| TrusteePrincipalID | int | UDF column | | +| SourceTrusteeID | int | SA_FSAA_Exceptions.SourceTrusteeID | | +| SourceTrusteeSID | varchar(184) | SA_FSAA_Trustees.SID (second join) | | +| SourceTrusteeType | smallint | SA_FSAA_Trustees.TrusteeType (second join) | | +| SourceTrusteeDisplayName | nvarchar(256) | UDF column | | +| SourceTrusteeNTStyleName | nvarchar(385) | Computed | | +| SourceTrusteePrincipalID | int | UDF column | | + +### SA_FSAA_AzureFilesPermissionsView {#sa_fsaa_azurefilespermissionsview} + +Created only when `SA_Entra_RmResources` exists. Joins Azure Files shares to the Entra ID role assignments captured by the Entra inventory collector to surface RBAC on Azure Files. + +**Source tables:** `SA_FSAA_AzureFilesShares`, `SA_Entra_RmResources` (filtered to `Microsoft.Storage/storageAccounts`), `SA_Entra_RmResourcesPrincipalsRolesView` + +| Column | Type | Source | Description | +|---|---|---|---| +| TenantID | varchar(38) | SA_Entra_RmResources.DomainId | | +| HOST | int | SA_FSAA_AzureFilesShares.HOST | | +| StorageAccount | varchar(256) | SA_FSAA_AzureFilesShares.StorageAccount | | +| Scope | nvarchar(512) | SA_Entra_RmResourcesPrincipalsRolesView.Scope | RBAC assignment scope | +| AzureShareId | int | SA_FSAA_AzureFilesShares.ID | | +| ResourceAzureId | varchar(512) | SA_Entra_RmResourcesPrincipalsRolesView.ResourceAzureId | | +| ProviderName | varchar(128) | SA_Entra_RmResources.ProviderName | | +| Type | varchar(128) | SA_Entra_RmResources.Type | | +| Resource Name | nvarchar(2000) | SA_FSAA_AzureFilesShares.Name | Share name | +| RoleDomainId | varchar(38) | SA_Entra_RmResourcesPrincipalsRolesView.RoleDomainId | | +| RoleDomainName | nvarchar(256) | SA_Entra_RmResourcesPrincipalsRolesView.RoleDomainName | | +| RoleId | varchar(38) | SA_Entra_RmResourcesPrincipalsRolesView.RoleId | | +| RoleName | nvarchar(256) | SA_Entra_RmResourcesPrincipalsRolesView.RoleName | | +| CreatedBy | nvarchar(256) | SA_Entra_RmResourcesPrincipalsRolesView.CreatedByDisplayName | | +| CreatedDateTime | datetime2 | SA_Entra_RmResourcesPrincipalsRolesView.CreatedDateTime | | +| ModifiedBy | nvarchar(256) | SA_Entra_RmResourcesPrincipalsRolesView.ModifiedByDisplayName | | +| ModifiedDateTime | datetime2 | SA_Entra_RmResourcesPrincipalsRolesView.ModifiedDateTime | | +| RightsFlags | int | SA_Entra_RmResourcesPrincipalsRolesView.RightsFlags | Custom-role rights bitmask | +| DataRightsFlags | int | SA_Entra_RmResourcesPrincipalsRolesView.DataRightsFlags | Custom-role data-action bitmask | + +## Activity Views (SA_FSAC_*) + +### SA_FSAC_DailyActivityView {#sa_fsac_dailyactivityview} + +Per-`(host, date, folder, trustee, operation)` activity row with trustee identity expanded and operation code translated to a human-readable label. The most common entry point for activity reporting. + +**Source tables:** `SA_FSAC_DailyActivity`, `SA_FSAA_Hosts`, `SA_FSAA_Trustees`, UDF `SA_FSAA_GetTrusteeInformationEx`, UDF `SA_FSAA_GetPath` + +| Column | Type | Source | Description | +|---|---|---|---| +| HostID | int | SA_FSAC_DailyActivity.HOST | | +| HostName | nvarchar(64) | SA_FSAA_Hosts.HOST | | +| ActivityDate | date | SA_FSAC_DailyActivity.ActivityDate | | +| FolderID | bigint | SA_FSAC_DailyActivity.FolderID | | +| Path | nvarchar(4000) | UDF: SA_FSAA_GetPath | Full folder path | +| UserID | int | SA_FSAC_DailyActivity.TrusteeID | | +| UserSID | varchar(184) | SA_FSAA_Trustees.SID | | +| UserType | smallint | UDF column | See [TrusteeType](../enumeration/overview.md#trusteetype) | +| UserPrincipalID | int | UDF column | AD-Inventory principal ID | +| UserTypeDescription | varchar(18) | Computed (CASE) | e.g. `Domain User` | +| UserDisplayName | nvarchar(256) | UDF column | | +| UserNTName | nvarchar(256) | UDF column | | +| UserNTDomain | nvarchar(128) | UDF column | | +| UserNTStyleName | nvarchar(385) | Computed (`Domain\Name`) | | +| Operation | tinyint | SA_FSAC_DailyActivity.Operation | | +| OperationDescription | varchar(18) | Computed (CASE) | `Read` / `Add` / `Update` / `Delete` / `Permission Change` / `Rename` | +| Allow | bit | SA_FSAC_DailyActivity.Allow | | +| AllowDescription | varchar(7) | Computed (CASE) | `Allowed` / `Denied` | +| OperationCount | int | SA_FSAC_DailyActivity.Count | | + +### SA_FSAC_DailyUserActivityView {#sa_fsac_dailyuseractivityview} + +Pivoted version of `SA_FSAC_DailyActivityView` — one row per `(host, date, folder, user)` with separate columns for each operation type's count. Filtered to `Allow = 1` (allowed operations only). + +**Source tables:** `SA_FSAC_DailyActivity` (pivoted on Operation), `SA_FSAA_Hosts`, `SA_FSAA_Trustees`, UDF `SA_FSAA_GetTrusteeInformationEx`, UDF `SA_FSAA_GetPath` + +| Column | Type | Source | Description | +|---|---|---|---| +| HostID | int | SA_FSAC_DailyActivity.HOST | | +| HostName | nvarchar(64) | SA_FSAA_Hosts.HOST | | +| ActivityDate | date | SA_FSAC_DailyActivity.ActivityDate | | +| FolderID | bigint | SA_FSAC_DailyActivity.FolderID | | +| Path | nvarchar(4000) | UDF: SA_FSAA_GetPath | | +| UserID | int | SA_FSAC_DailyActivity.TrusteeID | | +| UserSID | varchar(184) | SA_FSAA_Trustees.SID | | +| UserType | smallint | UDF column | | +| UserPrincipalID | int | UDF column | | +| UserTypeDescription | varchar(18) | Computed (CASE) | | +| UserDisplayName | nvarchar(256) | UDF column | | +| UserNTName | nvarchar(256) | UDF column | | +| UserNTDomain | nvarchar(128) | UDF column | | +| UserNTStyleName | nvarchar(385) | Computed | | +| Reads | int | Pivot (Operation = 0) | Read-operation count | +| Adds | int | Pivot (Operation = 1) | Add-operation count | +| Updates | int | Pivot (Operation = 2) | Update-operation count | +| Deletes | int | Pivot (Operation = 3) | Delete-operation count | +| PermissionChanges | int | Pivot (Operation = 4) | Permission-change count | +| Renames | int | Pivot (Operation = 5) | Rename count | + +### SA_FSAC_DailyResourceActivityView {#sa_fsac_dailyresourceactivityview} + +Same shape as `SA_FSAC_DailyUserActivityView` but rolled up across users — one row per `(host, date, folder)` with operation counts and a count of distinct active users. + +**Source tables:** `SA_FSAC_DailyActivity` (pivoted on Operation, then aggregated), `SA_FSAA_Hosts`, UDF `SA_FSAA_GetPath` + +| Column | Type | Source | Description | +|---|---|---|---| +| HostID | int | SA_FSAC_DailyActivity.HOST | | +| HostName | nvarchar(64) | SA_FSAA_Hosts.HOST | | +| ActivityDate | date | SA_FSAC_DailyActivity.ActivityDate | | +| FolderID | bigint | SA_FSAC_DailyActivity.FolderID | | +| Path | nvarchar(4000) | UDF: SA_FSAA_GetPath | | +| Reads | int | SUM (Operation = 0) | | +| Adds | int | SUM (Operation = 1) | | +| Updates | int | SUM (Operation = 2) | | +| Deletes | int | SUM (Operation = 3) | | +| PermissionChanges | int | SUM (Operation = 4) | | +| Renames | int | SUM (Operation = 5) | | +| ActiveUsers | int | COUNT(DISTINCT TrusteeID) | Distinct users with activity that day | + +### SA_FSAC_ActivityEventsView {#sa_fsac_activityeventsview} + +Detailed event view — one row per `SA_FSAC_ActivityEvents` row, joined to resource metadata, process name, trustee identity, and (for renames) the rename target. + +**Source tables:** `SA_FSAC_ActivityEvents`, `SA_FSAA_Hosts`, `SA_FSAC_ProcessNames`, `SA_FSAA_Resources`, `SA_FSAA_Trustees`, `SA_FSAC_RenameTargets`, UDF `SA_FSAA_GetTrusteeInformationEx`, UDF `SA_FSAA_GetPath` + +| Column | Type | Source | Description | +|---|---|---|---| +| HostID | int | SA_FSAC_ActivityEvents.HOST | | +| HostName | nvarchar(64) | SA_FSAA_Hosts.HOST | | +| ID | bigint | SA_FSAC_ActivityEvents.ID | | +| AccessTime | datetime2 | SA_FSAC_ActivityEvents.AccessTime | | +| ResourceID | bigint | SA_FSAC_ActivityEvents.PathID | | +| ResourceType | tinyint | SA_FSAA_Resources.ResourceType | | +| ResourceTypeDescription | varchar(6) | Computed (CASE) | `Folder` / `File` | +| ParentResourceID | bigint | SA_FSAA_Resources.ParentResourceID | | +| ResourceName | nvarchar(2000) | SA_FSAA_Resources.Name | | +| Path | nvarchar(4000) | UDF: SA_FSAA_GetPath | | +| ProcessID | int | SA_FSAC_ActivityEvents.ProcessID | | +| ProcessName | nvarchar(255) | SA_FSAC_ProcessNames.Name | | +| Operation | tinyint | SA_FSAC_ActivityEvents.Operation | | +| OperationDescription | varchar(18) | Computed (CASE) | | +| Allow | bit | SA_FSAC_ActivityEvents.Allow | | +| AllowDescription | varchar(7) | Computed (CASE) | `Allowed` / `Denied` | +| TargetResourceID | bigint | SA_FSAC_RenameTargets.TargetPathID | Renames only | +| TargetResourceName | nvarchar(2000) | SA_FSAA_Resources.Name (target) | Renames only | +| TargetParentResourceID | bigint | SA_FSAA_Resources.ParentResourceID (target) | Renames only | +| TargetPath | nvarchar(4000) | UDF: SA_FSAA_GetPath (target) | Renames only | +| UserID | int | SA_FSAC_ActivityEvents.TrusteeID | | +| UserSID | varchar(184) | SA_FSAA_Trustees.SID | | +| UserDisplayName | nvarchar(256) | UDF column | | +| UserNTDomain | nvarchar(128) | UDF column | | +| UserNTName | nvarchar(256) | UDF column | | +| UserType | smallint | UDF column | | +| UserPrincipalID | int | UDF column | | +| UserTypeDescription | varchar(18) | Computed (CASE) | | +| UserNTStyleName | nvarchar(385) | Computed | | + +### SA_FSAC_ExceptionsView {#sa_fsac_exceptionsview} + +`SA_FSAC_Exceptions` joined to the type catalog and to the trustee/gate/resource references, with day-of-week and time-of-day translations. + +**Source tables:** `SA_FSAC_Exceptions`, `SA_FSAC_ExceptionTypes`, `SA_FSAA_Hosts`, `SA_FSAA_Gates`, `SA_FSAA_Resources`, UDF `SA_FSAA_GetPath`, UDF `SA_FSAA_GetTrusteeInformation` + +| Column | Type | Source | Description | +|---|---|---|---| +| HostID | int | SA_FSAC_Exceptions.HOST | | +| HostName | nvarchar(64) | SA_FSAA_Hosts.HOST | | +| ID | int | SA_FSAC_Exceptions.ID | | +| ExceptionType | int | SA_FSAC_Exceptions.ExceptionType | | +| ParentType | int | SA_FSAC_ExceptionTypes.ParentType | | +| ExceptionName | varchar(128) | SA_FSAC_ExceptionTypes.Name | | +| ActivityDate | date | SA_FSAC_Exceptions.ActivityDate | | +| ActivityHour | tinyint | SA_FSAC_Exceptions.ActivityHour | | +| DayOfWeek | nvarchar(30) | Computed (`DATENAME(dw, ActivityDate)`) | e.g. `Monday` | +| TimeOfDay | varchar(8) | Computed (CASE on ActivityHour) | e.g. `3 PM`, `12 AM` | +| GateID | int | SA_FSAC_Exceptions.GateID | | +| ResourceID | bigint | SA_FSAC_Exceptions.ResourceID | | +| Path | nvarchar(4000) | Computed (`\\host\share`) | | +| TrusteeID | int | SA_FSAC_Exceptions.TrusteeID | | +| TrusteeDisplayName | nvarchar(256) | UDF: SA_FSAA_GetTrusteeInformation | | +| NTDomain | nvarchar(128) | UDF column | | +| NTName | nvarchar(256) | UDF column | | +| TrusteeNTStyleName | nvarchar(385) | Computed (`Domain\Name`) | | +| TrusteeType | smallint | UDF column | | +| TrusteeTypeDescription | varchar(18) | Computed (CASE) | | +| TrusteeSID | varchar(184) | UDF column | | +| TrusteePrincipalID | int | UDF column | | +| Value | int | SA_FSAC_Exceptions.Value | | +| Average | float | SA_FSAC_Exceptions.Average | | +| StandardDeviations | float | SA_FSAC_Exceptions.StandardDeviations | | + +### SA_FSAC_UserExceptionsView {#sa_fsac_userexceptionsview} + +Same shape as `SA_FSAC_ExceptionsView` but partitioned by user `SID` rather than `(HOST, ID)`. Used for cross-host user-behaviour anomalies. + +**Source tables:** `SA_FSAC_UserExceptions`, `SA_FSAC_UserExceptionTypes` + +Columns mirror `SA_FSAC_ExceptionsView` minus the per-host columns: `SID`, `ID`, `ExceptionType`, `ParentType`, `ExceptionName`, `ActivityDate`, `ActivityStartTime`, `ActivityPeriod`, `Value`, `Average`, `StandardDeviations`, plus computed `DayOfWeek` and `TimeOfDay`. + +### SA_FSAC_PermissionChangesView {#sa_fsac_permissionchangesview} + +Per-permission-change view that joins each `SA_FSAC_PermissionChanges` detail row to its host and resolves the affected trustee via `SA_FSAA_GetTrusteeInformation`. Does not join to `SA_FSAC_ActivityEvents` or `SA_FSAA_Resources`; use `SA_FSAC_ActivityEventsView` joined to `SA_FSAC_PermissionChanges` when `AccessTime`, `ResourcePath`, or `ResourceType` are needed. + +**Source tables:** `SA_FSAC_PermissionChanges`, `SA_FSAA_Hosts`, CROSS APPLY `SA_FSAA_GetTrusteeInformation` + +| Column | Type | Source | Description | +|---|---|---|---| +| HostID | int | SA_FSAC_PermissionChanges.HOST | Host partition | +| HostName | nvarchar(64) | SA_FSAA_Hosts.HOST | Host name | +| ActivityID | bigint | SA_FSAC_PermissionChanges.ActivityID | Parent activity event ID | +| ChangeID | smallint | SA_FSAC_PermissionChanges.ChangeID | Per-event change index | +| AclType | tinyint | SA_FSAC_PermissionChanges.AclType | ACL type (DACL / SACL) | +| AclTypeDescription | varchar | Computed (CASE) | Decoded ACL type label | +| TrusteeID | int | SA_FSAC_PermissionChanges.TrusteeID | Trustee whose ACE changed | +| TrusteeSID | varchar(184) | UDF: SA_FSAA_GetTrusteeInformation | | +| TrusteeType | smallint | UDF column | See [TrusteeType](../enumeration/overview.md#trusteetype) | +| TrusteeTypeDescription | varchar | Computed (CASE) | e.g. `Domain User` | +| PrincipalId | int | UDF column | AD-Inventory principal ID | +| DisplayName | nvarchar(256) | UDF column | | +| NTDomain | nvarchar(128) | UDF column | | +| NTName | nvarchar(256) | UDF column | | +| TrusteeNTStyleName | nvarchar(385) | Computed (`Domain\Name`) | | +| ChangeType | tinyint | SA_FSAC_PermissionChanges.ChangeType | Added / Removed / Modified | +| ChangeTypeDescription | varchar | Computed (CASE) | Decoded change-type label | +| AceType | tinyint | SA_FSAC_PermissionChanges.AceType | Allow / Deny | +| AceTypeDescription | varchar | Computed (CASE) | Decoded ACE-type label | +| InheritanceFlags | tinyint | SA_FSAC_PermissionChanges.InheritanceFlags | NTFS inheritance flags | +| InheritanceFlagsDescription | varchar | Computed (CASE) | Decoded inheritance-flags label | +| AceFlags | tinyint | SA_FSAC_PermissionChanges.AceFlags | NTFS ACE flags | +| AceFlagsDescription | varchar | Computed (CASE) | Decoded ACE-flags label | +| AccessRights | bigint | SA_FSAC_PermissionChanges.AccessRights | Pre-change Windows access mask | +| NewAccessRights | bigint | SA_FSAC_PermissionChanges.NewAccessRights | Post-change access mask (NULL when ACE removed) | +| AccessRightsDescription | varchar | Computed (CASE) | Decoded pre-change rights label | +| NewAccessRightsDescription | varchar | Computed (CASE) | Decoded post-change rights label | + +## Sensitive Data Views (SA_FSDLP_*) + +### SA_FSDLP_MatchesView {#sa_fsdlp_matchesview} + +`SA_FSDLP_Matches` enriched with file path, criterion name and GUID, a human-readable `DataSource` description, and an `IsExcluded` flag computed from the SDD exclusion-filter table. + +**Source tables:** `SA_FSDLP_Matches`, `SA_FSAA_Hosts`, `SA_FSDLP_Criteria`, `SA_FSAA_Resources`, `SA_FSAA_SharesTraversalView`, `SA_SDDExclusionFilters`, UDF `SA_FSAA_GetPath` + +| Column | Type | Source | Description | +|---|---|---|---| +| HostID | int | SA_FSDLP_Matches.HOST | | +| HostName | nvarchar(64) | SA_FSAA_Hosts.HOST | | +| CriteriaId | int | SA_FSDLP_Matches.CriteriaId | | +| CriteriaName | nvarchar(256) | SA_FSDLP_Criteria.Name | | +| CriteriaGUID | uniqueidentifier | SA_FSDLP_Criteria.pattern_guid | | +| ResourceID | bigint | SA_FSDLP_Matches.FileId | | +| ParentResourceID | bigint | SA_FSAA_Resources.ParentResourceID | | +| FileName | nvarchar(2000) | SA_FSAA_Resources.Name | | +| FilePath | nvarchar(4000) | UDF: SA_FSAA_GetPath | | +| MatchCount | int | SA_FSDLP_Matches.MatchCount | | +| DataSource | varchar(30) | Computed (CASE) | `Content` / `Metadata` / `Filename` / combinations | +| IsExcluded | bit | Computed (EXISTS against `SA_SDDExclusionFilters`) | True if the file is covered by an exclusion filter | + +### SA_FSDLP_MatchHitsView {#sa_fsdlp_matchhitsview} + +`SA_FSDLP_MatchHits` joined to `SA_FSDLP_MatchesView` so each hit carries the parent file/criterion identity. Used by the Sensitive Data report's drill-down view. + +**Source tables:** `SA_FSDLP_MatchHits`, `SA_FSDLP_MatchesView` + +| Column | Type | Source | Description | +|---|---|---|---| +| HostID | int | SA_FSDLP_MatchesView.HostID | | +| HostName | nvarchar(64) | SA_FSDLP_MatchesView.HostName | | +| CriteriaID | int | SA_FSDLP_MatchesView.CriteriaId | | +| CriteriaName | nvarchar(256) | SA_FSDLP_MatchesView.CriteriaName | | +| CriteriaGUID | uniqueidentifier | SA_FSDLP_MatchesView.CriteriaGUID | | +| ResourceID | bigint | SA_FSDLP_MatchesView.ResourceID | | +| ParentResourceID | bigint | SA_FSDLP_MatchesView.ParentResourceID | | +| FileName | nvarchar(2000) | SA_FSDLP_MatchesView.FileName | | +| FilePath | nvarchar(4000) | SA_FSDLP_MatchesView.FilePath | | +| MatchCount | int | SA_FSDLP_MatchesView.MatchCount | | +| SubFileName | nvarchar(1024) | SA_FSDLP_MatchHits.SubFileName | | +| MatchPrefix | nvarchar(1024) | SA_FSDLP_MatchHits.MatchPrefix | | +| MatchData | nvarchar(1024) | SA_FSDLP_MatchHits.MatchData | | +| MatchSuffix | nvarchar(1024) | SA_FSDLP_MatchHits.MatchSuffix | | +| Confidence | int | SA_FSDLP_MatchHits.Confidence | | +| DataSource | varchar(30) | Computed (CASE on `SA_FSDLP_MatchHits.DataSource`) | Same vocabulary as `SA_FSDLP_MatchesView.DataSource` | diff --git a/docs/accessanalyzer/12.0/admin/schema/overview.md b/docs/accessanalyzer/12.0/admin/schema/overview.md index aac24ae38a..92b9957343 100644 --- a/docs/accessanalyzer/12.0/admin/schema/overview.md +++ b/docs/accessanalyzer/12.0/admin/schema/overview.md @@ -14,3 +14,14 @@ The SQL Data Collector discovers, audits, and reports on SQL Server instances, d - **[Index Reference](sqldc/indexreference/overview.md)** — Documentation of database indexes - **[Functions & Stored Procedures](sqldc/functions/overview.md)** — SQL scalar functions and stored procedures +## [File System Access Analyzer DC Schema](fsaadc/overview.md) + +The File System Access Analyzer data collector audits Windows, NFS, and Azure Files file systems for permissions, ownership, content, activity, and sensitive-data classification across four sub-modules (SA_FSAA_, SA_FSAC_, SA_FSDLP_, SA_FSDFS_). The schema documentation covers: + +- **[Table Relationship Diagrams (ERD)](fsaadc/erd/overview.md)** — Visual ERDs showing table relationships across all four collector modules +- **[Core Data Collection Tables](fsaadc/coretables/overview.md)** — 47 normalized tables populated directly by data collectors, partitioned by host with full foreign key relationships +- **[Views](fsaadc/views/overview.md)** — 20 SQL views that join and denormalize data for reporting +- **[Enumeration & Lookup Values](fsaadc/enumeration/overview.md)** — Reference for coded values including TrusteeType, ResourceType, GateType, and the six-bit rights bitmask +- **[Functions & Stored Procedures](fsaadc/functions/overview.md)** — 29 UDFs and stored procedures covering path resolution, effective-access computation, group membership expansion, and DFS path lookup +- **[Index Reference](fsaadc/indexreference/overview.md)** — Complete listing of database indexes across all FSAA DC tables +- **[Foreign Key Reference](fsaadc/fkreference/overview.md)** — Complete listing of foreign key constraints and cascade behaviors From f717ae10a19f5845f1ec0d0e3ad736c362a86572 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 22:32:52 +0000 Subject: [PATCH 2/4] fix(vale): auto-fix style issues (Vale + Dale) --- .../12.0/admin/schema/fsaadc/coretables/overview.md | 4 ++-- .../12.0/admin/schema/fsaadc/enumeration/overview.md | 6 +++--- .../12.0/admin/schema/fsaadc/erd/overview.md | 12 ++++++------ .../12.0/admin/schema/fsaadc/fkreference/overview.md | 2 +- .../12.0/admin/schema/fsaadc/functions/overview.md | 4 ++-- .../12.0/admin/schema/fsaadc/overview.md | 2 +- .../12.0/admin/schema/fsaadc/views/overview.md | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/overview.md index 97aae1b058..66b42c7806 100644 --- a/docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/overview.md +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/overview.md @@ -831,7 +831,7 @@ Per-host catalog of the DLP criteria (patterns / classifiers) that produced matc |---|---|---|---|---|---|---|---| | HOST | int | | No | PK | FK → SA_FSAA_Hosts.ID | | Host partition | | ID | int | | No | PK | | | Per-host criterion ID | -| Name | nvarchar | 256 | No | | | | Criterion name (e.g. "US Social Security Number") | +| Name | nvarchar | 256 | No | | | | Criterion name (e.g. "United States Social Security Number") | | Risk | int | | No | | | `0` | Risk score | | pattern_guid | uniqueidentifier | | Yes | | | | Global criterion GUID | @@ -951,7 +951,7 @@ Each DFS link maps a logical DFS path (e.g. `\\contoso.com\public\sales`) to a p | Timeout | int | | Yes | | | | DFS-link cache timeout | | DfsGuid | uniqueidentifier | | Yes | | | | DFS link's unique identifier | | Comment | nvarchar | 1024 | Yes | | | | Free-text comment | -| IsRoot | bit | | No | | | | True if this link represents the namespace root rather than a sub-link | +| IsRoot | bit | | No | | | | True if the DFS link represents the namespace root rather than a sub-link | **Primary Key:** `PK_SA_FSDFS_Links` — clustered on `(HOST, ID)` **Foreign Keys:** diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/overview.md index 02dcc9ec63..227d48c3c0 100644 --- a/docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/overview.md +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/overview.md @@ -8,7 +8,7 @@ Used in `SA_FSAA_Trustees.TrusteeType` and `SA_FSAA_LocalTrustees.TrusteeType`. | Value | Name | Description | |---|---|---| -| 0 | Unknown | Type could not be determined | +| 0 | Unknown | Type couldn't be determined | | 1 | SecurityPrincipal | Built-in / well-known security principal (e.g. `Everyone`) | | 2 | LocalUser | Local user account | | 3 | LocalGroup | Local group account | @@ -23,7 +23,7 @@ Used in `SA_FSAA_Trustees.TrusteeType` and `SA_FSAA_LocalTrustees.TrusteeType`. | 20 | UnixUser | POSIX user | | 21 | UnixGroup | POSIX group | -The `TrusteeTypeDescription` column in views covers values 0, 1, 2, 3, 4, 5, 8, 9, and 10. Values 6, 7, 11, 20, and 21 do not have a dedicated description string in the current view CASE expressions. +The `TrusteeTypeDescription` column in views covers values 0, 1, 2, 3, 4, 5, 8, 9, and 10. Values 6, 7, 11, 20, and 21 don't have a dedicated description string in the current view CASE expressions. ## ResourceType {#resourcetype} @@ -93,4 +93,4 @@ The full Windows access mask is stored separately in the `*Mask` columns. The fo | 1114112 | Delete | | 1179648 | Read Permissions | -Additional special-permission decimal values are decoded by an extended `CASE` expression in the permission views; the values listed above cover the most commonly encountered masks. +Additional special-permission decimal values are decoded by an extended `CASE` expression in the permission views; the listed values cover the most commonly encountered masks. diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/overview.md index 45c9f11bff..d9fb3f9523 100644 --- a/docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/overview.md +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/overview.md @@ -1,14 +1,14 @@ # Table Relationship Diagrams (ERD) -Relationship lines use standard crow's foot notation: a single vertical bar on the parent side and a crow's foot (fork) on the child side means "exactly one parent, zero or more children"; a single bar on each side with an open circle means one-to-zero-or-one (sidecar / extension table). +Relationship lines use standard crow's foot notation: a single vertical bar on the parent side and a crow's foot (fork) on the child side means "exactly one parent and zero or more children"; a single bar on each side with an open circle means one-to-zero-or-one (sidecar / extension table). :::note -Every core table includes a `HOST INT` column that is a foreign key to `SA_FSAA_Hosts.ID` with `ON DELETE CASCADE`. To keep the sub-diagrams readable, the host fan-out is shown only in the top-level diagrams below; in the other diagrams `HOST` is implicit on every relationship. Three tables are not shown in any diagram because they carry no foreign keys: `SA_FSAA_SchemaVer` (single-row config), `SA_FSAA_ScanHistory` (audit log), and `SA_FSAA_AzureStorageAccounts` (single-column lookup). +Every core table includes a `HOST INT` column that is a foreign key to `SA_FSAA_Hosts.ID` with `ON DELETE CASCADE`. To keep the sub-diagrams readable, the host fan-out is shown only in the following top-level diagrams; in the other diagrams `HOST` is implicit on every relationship. Three tables aren't shown in any diagram because they carry no foreign keys: `SA_FSAA_SchemaVer` (single-row config), `SA_FSAA_ScanHistory` (audit log), and `SA_FSAA_AzureStorageAccounts` (single-column lookup). ::: ## Top-level Partitioning {#top-level-partitioning} -`SA_FSAA_Hosts` is the root of the schema. Every other table includes a `HOST` column whose foreign key cascades on delete, so removing a host atomically purges its entire data set. Because the host fan-out spans more than six child tables, it is split into two diagrams below. +`SA_FSAA_Hosts` is the root of the schema. Every other table includes a `HOST` column whose foreign key cascades on delete, so removing a host atomically purges its entire data set. Because the host fan-out spans more than six child tables, it is split into the following two diagrams. **Core structural and permission tables:** @@ -81,7 +81,7 @@ A "gate" is a way to reach a resource — an SMB share, NFS export, or LSA-polic ``` :::note -`SA_FSAA_Resources.RightsProxyID → SA_FSAA_Rights.RightsProxyID` and `SA_FSAA_Resources.GatesProxyID → SA_FSAA_GatesProxy.ID` are logical (un-enforced) references not shown above. These are denormalized pointers maintained by the import pipeline; no FK constraint is created so that bulk imports can stage rows in any order. +`SA_FSAA_Resources.RightsProxyID → SA_FSAA_Rights.RightsProxyID` and `SA_FSAA_Resources.GatesProxyID → SA_FSAA_GatesProxy.ID` are logical (un-enforced) references not shown in the diagram. These are denormalized pointers maintained by the import pipeline; no FK constraint is created so that bulk imports can stage rows in any order. ::: ## Tags {#tags} @@ -119,7 +119,7 @@ Tags use a three-table dedup pattern. `SA_FSAA_Tags` holds each unique tag strin ## Activity Collection (SA_FSAC_*) {#activity-collection} -`SA_FSAC_ActivityEvents` is the audit-event firehose; each row is one observed file-system operation. Every event references the resource (`PathID`), the trustee that performed the operation, and the process (`ProcessID`) that ran it. Three detail tables hang off `ActivityEvents`: `SA_FSAC_PermissionChanges`, `SA_FSAC_OwnerChanges`, and `SA_FSAC_RenameTargets`. `SA_FSAC_DailyActivity` is a daily aggregation rolled up by `(folder, trustee, operation)`. `SA_FSAC_Exceptions` records detected anomalies; `SA_FSAC_UserExceptions` is the per-user variant (partitioned by `SID` instead of by host). +`SA_FSAC_ActivityEvents` is the audit-event firehose; each row is one observed file-system operation. Every event references the resource (`PathID`), the trustee that performed the operation, and the process (`ProcessID`) that ran it. Three detail tables reference `ActivityEvents`: `SA_FSAC_PermissionChanges`, `SA_FSAC_OwnerChanges`, and `SA_FSAC_RenameTargets`. `SA_FSAC_DailyActivity` is a daily aggregation rolled up by `(folder, trustee, operation)`. `SA_FSAC_Exceptions` records detected anomalies; `SA_FSAC_UserExceptions` is the per-user variant (partitioned by `SID` instead of by host). ```erDiagram SA_FSAA_Hosts ||--o{ SA_FSAC_ProcessNames : "HOST" @@ -159,7 +159,7 @@ Tags use a three-table dedup pattern. `SA_FSAA_Tags` holds each unique tag strin ``` :::note -`SA_FSDLP_Matches.FileId → SA_FSAA_Resources.ID` is a logical (un-enforced) reference not shown above. The DLP collector populates `FileId` to match the FSAA resource ID but no SQL FK constraint is created, so DLP imports can run independently of structural scans. `SA_FSDLP_MatchHits_SubjectProfile` also has foreign keys into the central Subject Profile tables (`SA_SubjectProfile_Sources`, `SA_SubjectProfile_Identities`, `SA_SubjectProfile_AttributeValues`), which are owned by a separate module and not shown here. +`SA_FSDLP_Matches.FileId → SA_FSAA_Resources.ID` is a logical (un-enforced) reference not shown in the diagram. The DLP collector populates `FileId` to match the FSAA resource ID but no SQL FK constraint is created, so DLP imports can run independently of structural scans. `SA_FSDLP_MatchHits_SubjectProfile` also has foreign keys into the central Subject Profile tables (`SA_SubjectProfile_Sources`, `SA_SubjectProfile_Identities`, `SA_SubjectProfile_AttributeValues`), which are owned by a separate module and not shown here. ::: ## DFS Namespaces (SA_FSDFS_*) {#dfs-namespaces} diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/fkreference/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/fkreference/overview.md index eb433b9ab5..c8ae6d85ec 100644 --- a/docs/accessanalyzer/12.0/admin/schema/fsaadc/fkreference/overview.md +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/fkreference/overview.md @@ -4,7 +4,7 @@ All enforced FK constraints across the four FSAA DC collector modules, listed in the same order as the [Core Data Collection Tables](../coretables/overview.md) page. -| FK Name | Parent Table | Parent Column(s) | Referenced Table | Referenced Column(s) | On Delete | +| FK Name | Parent Table | Parent Columns | Referenced Table | Referenced Columns | On Delete | |---|---|---|---|---|---| | FK_SA_FSAA_ImportHistory_HOST | SA_FSAA_ImportHistory | HOST | SA_FSAA_Hosts | ID | CASCADE | | FK_SA_FSAA_Trustees_HOST | SA_FSAA_Trustees | HOST | SA_FSAA_Hosts | ID | CASCADE | diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/functions/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/functions/overview.md index ab1560e309..3b8cdb9088 100644 --- a/docs/accessanalyzer/12.0/admin/schema/fsaadc/functions/overview.md +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/functions/overview.md @@ -9,7 +9,7 @@ All functions and stored procedures live in the `dbo` schema. Most table-valued **Signature:** `(@serverID INT, @resourceID BIGINT) RETURNS NVARCHAR(4000)` **Type:** Scalar function -Walks the parent chain in `SA_FSAA_Resources` and concatenates names with the appropriate delimiter (`/` for Unix resources of type 5 or 6, `\` for everything else) to produce the full resource path. Returns NULL if the resource is not found. +Walks the parent chain in `SA_FSAA_Resources` and concatenates names with the appropriate delimiter (`/` for Unix resources of type 5 or 6, `\` for everything else) to produce the full resource path. Returns NULL if the resource isn't found. ### SA_FSAA_GetTrusteeMembership @@ -23,7 +23,7 @@ Recursively expands a group or principal into its effective members. Handles wel **Signature:** `(@serverID INT, @trusteeSID VARCHAR(184), @trusteeDomain NVARCHAR(256), @trusteeType INT, @groupSID VARCHAR(184), @groupDomain NVARCHAR(256), @groupType INT, @directlyApplied INT) RETURNS INT` **Type:** Scalar function -Returns `1` if the trustee is a recursive member of the group, else `0`. Encodes fast paths for `Everyone (S-1-1-0)`, `Authenticated Users (S-1-5-11)` (excluding Guest, Anonymous, and Domain Computers), and `Domain Users (S-1-5-21-...-513)`. Falls back to `SA_FSAA_GetTrusteeMembership` when the relationship cannot be answered by a fast path. +Returns `1` if the trustee is a recursive member of the group, else `0`. Encodes fast paths for `Everyone (S-1-1-0)`, `Authenticated Users (S-1-5-11)` (excluding Guest, Anonymous, and Domain Computers), and `Domain Users (S-1-5-21-...-513)`. Falls back to `SA_FSAA_GetTrusteeMembership` when the relationship can't be answered by a fast path. ### SA_FSAA_RecurseFolders diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/overview.md index f882f66120..fab2f0c81e 100644 --- a/docs/accessanalyzer/12.0/admin/schema/fsaadc/overview.md +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/overview.md @@ -4,7 +4,7 @@ The File System Access Analyzer (FSAA) data collector audits Windows, NFS, and A ### [Table Relationship Diagrams (ERD)](erd/overview.md) -- [Top-level partitioning — every table hangs off SA_FSAA_Hosts](erd/overview.md#top-level-partitioning) +- [Top-level partitioning — every table references SA_FSAA_Hosts](erd/overview.md#top-level-partitioning) - [Trustees — security-principal identity model](erd/overview.md#trustees) - [Resources & content aggregations](erd/overview.md#resources) - [Gates and permissions](erd/overview.md#gates-and-permissions) diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/views/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/views/overview.md index fc560da722..5dd3ba9131 100644 --- a/docs/accessanalyzer/12.0/admin/schema/fsaadc/views/overview.md +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/views/overview.md @@ -468,7 +468,7 @@ Columns mirror `SA_FSAC_ExceptionsView` minus the per-host columns: `SID`, `ID`, ### SA_FSAC_PermissionChangesView {#sa_fsac_permissionchangesview} -Per-permission-change view that joins each `SA_FSAC_PermissionChanges` detail row to its host and resolves the affected trustee via `SA_FSAA_GetTrusteeInformation`. Does not join to `SA_FSAC_ActivityEvents` or `SA_FSAA_Resources`; use `SA_FSAC_ActivityEventsView` joined to `SA_FSAC_PermissionChanges` when `AccessTime`, `ResourcePath`, or `ResourceType` are needed. +Per-permission-change view that joins each `SA_FSAC_PermissionChanges` detail row to its host and resolves the affected trustee via `SA_FSAA_GetTrusteeInformation`. Doesn't join to `SA_FSAC_ActivityEvents` or `SA_FSAA_Resources`; use `SA_FSAC_ActivityEventsView` joined to `SA_FSAC_PermissionChanges` when `AccessTime`, `ResourcePath`, or `ResourceType` are needed. **Source tables:** `SA_FSAC_PermissionChanges`, `SA_FSAA_Hosts`, CROSS APPLY `SA_FSAA_GetTrusteeInformation` From 9fa36c633e93bc7bf52b4b20f8905dc608d4125e Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 22:44:01 +0000 Subject: [PATCH 3/4] docs: fix idioms and define acronym in FSAA DC schema Replace 'firehose' and 'structural backbone' metaphors with literal descriptions per Netwrix style (no idioms or metaphors). Define FSAA on first use in the enumeration page. Co-Authored-By: Claude --- .../12.0/admin/schema/fsaadc/coretables/overview.md | 4 ++-- .../12.0/admin/schema/fsaadc/enumeration/overview.md | 2 +- docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/overview.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/overview.md index 66b42c7806..8a120fc639 100644 --- a/docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/overview.md +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/overview.md @@ -185,7 +185,7 @@ Membership of `Tags` in a `TagKeys` set: each row links one tag to one tag-proxy ### SA_FSAA_Resources {#sa_fsaa_resources} -The structural backbone — every share, folder, and file the DC has seen on the host, plus its parent linkage, owner, ACL pointer, gate pointer, tag pointer, sizing, and timestamps. This is the largest table in the schema by row count and is created `WITH (DATA_COMPRESSION = ROW)` on Enterprise editions. +The central resource inventory — every share, folder, and file the DC has seen on the host, plus its parent linkage, owner, ACL pointer, gate pointer, tag pointer, sizing, and timestamps. This is the largest table in the schema by row count and is created `WITH (DATA_COMPRESSION = ROW)` on Enterprise editions. `RightsProxyID`, `GatesProxyID`, and `TagProxyID` are logical (un-enforced) denormalized pointers; no FK constraints exist on them so that bulk imports can stage rows in any order. @@ -608,7 +608,7 @@ Per-host lookup of process names observed in audit events. Activity events refer ### SA_FSAC_ActivityEvents {#sa_fsac_activityevents} -The activity-event firehose. One row per audited file-system operation captured by an FSAC agent. `Operation` is a coded enumeration covering Read / Add / Update / Delete / PermissionChange / Rename. `Allow` is `1` for successful operations and `0` for denied operations. +The high-volume activity-event stream. One row per audited file-system operation captured by an FSAC agent. `Operation` is a coded enumeration covering Read / Add / Update / Delete / PermissionChange / Rename. `Allow` is `1` for successful operations and `0` for denied operations. :::note The `AccessTime` column type differs by environment: fresh-install DDL uses `datetime2`; the Task-15 migration recreates the table with `datetime`. Post-migration environments have `datetime`. diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/overview.md index 227d48c3c0..61f9dfaca8 100644 --- a/docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/overview.md +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/overview.md @@ -1,6 +1,6 @@ # Enumeration & Lookup Values -This page documents all coded column values and lookup tables used in the FSAA DC schema. Views surface most of these codes as human-readable description columns, but the raw values appear in the underlying tables and are useful for writing direct queries or custom reports. +This page documents all coded column values and lookup tables used in the File System Access Analyzer (FSAA) DC schema. Views surface most of these codes as human-readable description columns, but the raw values appear in the underlying tables and are useful for writing direct queries or custom reports. ## TrusteeType {#trusteetype} diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/overview.md index d9fb3f9523..86d31a1bda 100644 --- a/docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/overview.md +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/overview.md @@ -119,7 +119,7 @@ Tags use a three-table dedup pattern. `SA_FSAA_Tags` holds each unique tag strin ## Activity Collection (SA_FSAC_*) {#activity-collection} -`SA_FSAC_ActivityEvents` is the audit-event firehose; each row is one observed file-system operation. Every event references the resource (`PathID`), the trustee that performed the operation, and the process (`ProcessID`) that ran it. Three detail tables reference `ActivityEvents`: `SA_FSAC_PermissionChanges`, `SA_FSAC_OwnerChanges`, and `SA_FSAC_RenameTargets`. `SA_FSAC_DailyActivity` is a daily aggregation rolled up by `(folder, trustee, operation)`. `SA_FSAC_Exceptions` records detected anomalies; `SA_FSAC_UserExceptions` is the per-user variant (partitioned by `SID` instead of by host). +`SA_FSAC_ActivityEvents` is the high-volume audit-event stream; each row is one observed file-system operation. Every event references the resource (`PathID`), the trustee that performed the operation, and the process (`ProcessID`) that ran it. Three detail tables reference `ActivityEvents`: `SA_FSAC_PermissionChanges`, `SA_FSAC_OwnerChanges`, and `SA_FSAC_RenameTargets`. `SA_FSAC_DailyActivity` is a daily aggregation rolled up by `(folder, trustee, operation)`. `SA_FSAC_Exceptions` records detected anomalies; `SA_FSAC_UserExceptions` is the per-user variant (partitioned by `SID` instead of by host). ```erDiagram SA_FSAA_Hosts ||--o{ SA_FSAC_ProcessNames : "HOST" From 84ae8a0960d871fdf9217eef611df47fee535f72 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Fri, 15 May 2026 19:06:09 +0000 Subject: [PATCH 4/4] fix(vale): auto-fix style issues (Vale + Dale) --- .../12.0/admin/schema/fsaadc/coretables/overview.md | 4 ++-- .../12.0/admin/schema/fsaadc/enumeration/overview.md | 2 +- .../12.0/admin/schema/fsaadc/erd/overview.md | 2 +- .../12.0/admin/schema/fsaadc/functions/overview.md | 12 ++++++------ .../admin/schema/fsaadc/indexreference/overview.md | 2 +- .../12.0/admin/schema/fsaadc/views/overview.md | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/overview.md index 8a120fc639..44567564a8 100644 --- a/docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/overview.md +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/coretables/overview.md @@ -422,7 +422,7 @@ Histogram of file age buckets within each resource subtree. The eleven `FileCoun ### SA_FSAA_FileTags {#sa_fsaa_filetags} -Aggregated file count and size per `(resource, tag-set)`. Populated when AIP or sensitive-data tags are collected. +Aggregated file count and size per `(resource, tag-set)`. Populated when Azure Information Protection (AIP) or sensitive-data tags are collected. | Column | Type | Size | Nullable | PK | FK | Default | Description | |---|---|---|---|---|---|---|---| @@ -458,7 +458,7 @@ Append-only audit log of every scan run, including the FSAA configuration XML us ### SA_FSAA_AzureFilesShares {#sa_fsaa_azurefilesshares} -Catalog of Azure Files shares discovered on a host. Each share is linked back to a `SA_FSAA_Resources` row (the share root) and a `SA_FSAA_Gates` row (the share gate). `StorageAccount` carries the FQDN of the storage account. +Catalog of Azure Files shares discovered on a host. Each share links back to a `SA_FSAA_Resources` row (the share root) and a `SA_FSAA_Gates` row (the share gate). `StorageAccount` carries the FQDN of the storage account. | Column | Type | Size | Nullable | PK | FK | Default | Description | |---|---|---|---|---|---|---|---| diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/overview.md index 61f9dfaca8..52d43c4e28 100644 --- a/docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/overview.md +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/enumeration/overview.md @@ -4,7 +4,7 @@ This page documents all coded column values and lookup tables used in the File S ## TrusteeType {#trusteetype} -Used in `SA_FSAA_Trustees.TrusteeType` and `SA_FSAA_LocalTrustees.TrusteeType`. Identifies the class of security principal represented by a trustee row. +Used in `SA_FSAA_Trustees.TrusteeType` and `SA_FSAA_LocalTrustees.TrusteeType`. Identifies the class of security principal that a trustee row represents. | Value | Name | Description | |---|---|---| diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/overview.md index 86d31a1bda..2322db08a5 100644 --- a/docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/overview.md +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/erd/overview.md @@ -3,7 +3,7 @@ Relationship lines use standard crow's foot notation: a single vertical bar on the parent side and a crow's foot (fork) on the child side means "exactly one parent and zero or more children"; a single bar on each side with an open circle means one-to-zero-or-one (sidecar / extension table). :::note -Every core table includes a `HOST INT` column that is a foreign key to `SA_FSAA_Hosts.ID` with `ON DELETE CASCADE`. To keep the sub-diagrams readable, the host fan-out is shown only in the following top-level diagrams; in the other diagrams `HOST` is implicit on every relationship. Three tables aren't shown in any diagram because they carry no foreign keys: `SA_FSAA_SchemaVer` (single-row config), `SA_FSAA_ScanHistory` (audit log), and `SA_FSAA_AzureStorageAccounts` (single-column lookup). +Every core table includes a `HOST INT` column that is a foreign key to `SA_FSAA_Hosts.ID` with `ON DELETE CASCADE`. To keep the sub-diagrams readable, the host fan-out appears only in the following top-level diagrams; in the other diagrams `HOST` is implicit on every relationship. Three tables don't appear in any diagram because they carry no foreign keys: `SA_FSAA_SchemaVer` (single-row config), `SA_FSAA_ScanHistory` (audit log), and `SA_FSAA_AzureStorageAccounts` (single-column lookup). ::: ## Top-level Partitioning {#top-level-partitioning} diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/functions/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/functions/overview.md index 3b8cdb9088..e471922a42 100644 --- a/docs/accessanalyzer/12.0/admin/schema/fsaadc/functions/overview.md +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/functions/overview.md @@ -23,7 +23,7 @@ Recursively expands a group or principal into its effective members. Handles wel **Signature:** `(@serverID INT, @trusteeSID VARCHAR(184), @trusteeDomain NVARCHAR(256), @trusteeType INT, @groupSID VARCHAR(184), @groupDomain NVARCHAR(256), @groupType INT, @directlyApplied INT) RETURNS INT` **Type:** Scalar function -Returns `1` if the trustee is a recursive member of the group, else `0`. Encodes fast paths for `Everyone (S-1-1-0)`, `Authenticated Users (S-1-5-11)` (excluding Guest, Anonymous, and Domain Computers), and `Domain Users (S-1-5-21-...-513)`. Falls back to `SA_FSAA_GetTrusteeMembership` when the relationship can't be answered by a fast path. +Returns `1` if the trustee is a recursive member of the group, else `0`. Encodes fast paths for `Everyone (S-1-1-0)`, `Authenticated Users (S-1-5-11)` (excluding Guest, Anonymous, and Domain Computers), and `Domain Users (S-1-5-21-...-513)`. Falls back to `SA_FSAA_GetTrusteeMembership` when no fast path can answer the relationship. ### SA_FSAA_RecurseFolders @@ -44,7 +44,7 @@ Helper that walks an effective-membership path and accumulates the membership ch **Signature:** `(@serverID INT, @trusteeID INT, @objectSID VARCHAR(184), @trusteeType SMALLINT) RETURNS TABLE (NTDomain, NTName, DisplayName, SID, TrusteeType, IsHistoricalSID, PrincipalId)` **Type:** Inline table-valued function -Returns a single row of trustee identity. For local trustees the values come from `SA_FSAA_LocalTrustees`; for domain trustees they come from the AD inventory's `SA_ADInventory_*` tables matched by SID (handling SID History when `IsHistoricalSID = 1`). Two definitions exist in the script; the current version is chosen at runtime by the `#SA_ImportObject` helper. +Returns a single row of trustee identity. For local trustees the values come from `SA_FSAA_LocalTrustees`; for domain trustees they come from the AD inventory's `SA_ADInventory_*` tables matched by SID (handling SID History when `IsHistoricalSID = 1`). Two definitions exist in the script; the `#SA_ImportObject` helper chooses the current version at runtime. ### SA_FSAA_GetTrusteeInformation @@ -135,14 +135,14 @@ Resolves a backslash-delimited path string against the resource tree for a host **Signature:** `(@path NVARCHAR(1024)) RETURNS @results TABLE (HostID INT NOT NULL, HostName NVARCHAR(256) NOT NULL, GateID INT NOT NULL, ResourceID BIGINT NULL, ...)` **Type:** Multi-statement table-valued function -Parses a UNC path (`\\server\share\path`) and returns the matching host, gate, and resource. Used to map paths captured in DLP or Activity tables back into the FSAA structural keyspace. +Parses a UNC path (`\\server\share\path`) and returns the matching host, gate, and resource. Maps paths captured in DLP or Activity tables back into the FSAA structural keyspace. ### SA_FSAA_UpdateStatistics **Signature:** `()` **Type:** Stored procedure (no parameters) -Runs `UPDATE STATISTICS` on the FSAA tables. Invoked by the structural-import job after a bulk import to keep the SQL Server query optimizer's row-count estimates current. Long-running on large data sets. +Runs `UPDATE STATISTICS` on the FSAA tables. The structural-import job invokes this procedure after a bulk import to keep the SQL Server query optimizer's row-count estimates current. Long-running on large data sets. ## Activity Collector Functions {#activity-collector-functions} @@ -167,11 +167,11 @@ Translates a user's recent activity (within `@activityDays` days) on a folder su **Signature:** `(@path NVARCHAR(1024)) RETURNS @values TABLE (TargetHostID INT, TargetGateID INT, TargetResourceID BIGINT, TargetFolderPath NVARCHAR(1024) NOT NULL)` **Type:** Multi-statement table-valued function -Resolves a DFS-style path (e.g. `\\contoso.com\public\sales\reports`) by walking `SA_FSDFS_Links` to find the matching link and returning the underlying physical target — the host, gate, resource, and remaining sub-folder path beneath the link. Used to translate DFS-relative report rows back into FSAA structural identifiers. +Resolves a DFS-style path (e.g. `\\contoso.com\public\sales\reports`) by walking `SA_FSDFS_Links` to find the matching link and returning the underlying physical target — the host, gate, resource, and remaining sub-folder path beneath the link. Translates DFS-relative report rows back into FSAA structural identifiers. ## Shared Core Functions {#shared-core-functions} -These functions are created by the FSAA Create-Schema job (Task 26) but live in the shared `dbo` schema used across multiple data collector modules. They handle domain group membership expansion and trustee-permission resolution by integrating with AD Inventory tables. +The FSAA Create-Schema job (Task 26) creates these functions, but they live in the shared `dbo` schema used across multiple data collector modules. They handle domain group membership expansion and trustee-permission resolution by integrating with AD Inventory tables. ### SA_CORE_GetDomainGroupMembershipEx diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/indexreference/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/indexreference/overview.md index f34c9b799a..4e5bc912d5 100644 --- a/docs/accessanalyzer/12.0/admin/schema/fsaadc/indexreference/overview.md +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/indexreference/overview.md @@ -2,7 +2,7 @@ ## Complete Index Listing {#complete-index-listing} -All indexes across the four FSAA DC collector modules. Clustered primary-key indexes are listed alongside nonclustered supporting indexes. Tables with no indexes beyond their clustered PK are noted at the end of this page. +All indexes across the four FSAA DC collector modules. Clustered primary-key indexes are listed alongside nonclustered supporting indexes. Tables with no indexes beyond their clustered PK appear at the end of this page. | Table | Index Name | Type | Unique | Columns | |---|---|---|---|---| diff --git a/docs/accessanalyzer/12.0/admin/schema/fsaadc/views/overview.md b/docs/accessanalyzer/12.0/admin/schema/fsaadc/views/overview.md index 5dd3ba9131..730e4c32ec 100644 --- a/docs/accessanalyzer/12.0/admin/schema/fsaadc/views/overview.md +++ b/docs/accessanalyzer/12.0/admin/schema/fsaadc/views/overview.md @@ -22,7 +22,7 @@ Path map for every resource. Implemented as a VIEW (not a table) — the Create- ### SA_FSAA_ResourcesView {#sa_fsaa_resourcesview} -Surface view of `SA_FSAA_Resources` enriched with computed full path, resource-type description, three boolean permission flags (`PermissionChange`, `InheritedPermission`, `DirectPermission`), and Azure Files metadata. Two definitions exist; the Entra-aware variant is used when `SA_Entra_RmResources` exists. +Surface view of `SA_FSAA_Resources` enriched with computed full path, resource-type description, three boolean permission flags (`PermissionChange`, `InheritedPermission`, `DirectPermission`), and Azure Files metadata. Two definitions exist; the Entra-aware variant applies when `SA_Entra_RmResources` exists. **Source tables:** `SA_FSAA_Resources`, `SA_FSAA_Hosts`, `SA_FSAA_Rights`, `SA_FSAA_AzureFilesShares`, `SA_Entra_RmResources` (when present) @@ -468,7 +468,7 @@ Columns mirror `SA_FSAC_ExceptionsView` minus the per-host columns: `SID`, `ID`, ### SA_FSAC_PermissionChangesView {#sa_fsac_permissionchangesview} -Per-permission-change view that joins each `SA_FSAC_PermissionChanges` detail row to its host and resolves the affected trustee via `SA_FSAA_GetTrusteeInformation`. Doesn't join to `SA_FSAC_ActivityEvents` or `SA_FSAA_Resources`; use `SA_FSAC_ActivityEventsView` joined to `SA_FSAC_PermissionChanges` when `AccessTime`, `ResourcePath`, or `ResourceType` are needed. +Per-permission-change view that joins each `SA_FSAC_PermissionChanges` detail row to its host and resolves the affected trustee via `SA_FSAA_GetTrusteeInformation`. Doesn't join to `SA_FSAC_ActivityEvents` or `SA_FSAA_Resources`; use `SA_FSAC_ActivityEventsView` joined to `SA_FSAC_PermissionChanges` when you need `AccessTime`, `ResourcePath`, or `ResourceType`. **Source tables:** `SA_FSAC_PermissionChanges`, `SA_FSAA_Hosts`, CROSS APPLY `SA_FSAA_GetTrusteeInformation`