You're about to hand us client tax IDs.

That deserves more than a sentence in a privacy policy. Here's what protects them and who else touches them. Your Qualified Individual can put this straight in the vendor file.

Start here

What actually stands between a client's SSN and everyone else.

A tax ID is encrypted in the application before it ever reaches the database, so the column holds ciphertext and the plaintext is never written down. Open the account screen and you see the last four digits. Getting the whole number takes a second identity check, and that reveal is written to a log nobody can go back and edit.

Below is the detail behind that paragraph, and then the parts we haven't built. If you own the firm, the four cards here are probably enough. If you're the person who has to answer the questionnaire, keep reading. There's a subprocessor list and a map to the FTC Safeguards Rule further down.

Ciphertext, or nothing

A tax ID is sealed with AES-256-GCM in the application before it reaches the database, so the column holds ciphertext. If the encryption key is missing, the API answers 503 and refuses the write. It never falls back to storing the number in the clear.

Your rows, nobody else's

Everything stored is stamped with your firm, and every lookup is limited to your firm's records. An automatic check on every release makes sure no new feature can forget that rule.

A log that can't be rewritten

302 kinds of action land in an audit log your admins read and export themselves. The database refuses edits and deletions there: entries are added, never changed.

Read-only by design

There's no write path to QuickBooks Online or Xero in the code. Your clients' ledgers can't be changed from here, so there's nothing to misconfigure and nothing to roll back.

Encryption

What's sealed, and what happens when the key goes missing.

Field-level encryption covers the values that would ruin a client's year if they leaked. Each one is sealed with AES-256-GCM on the way in, and the database only ever sees the sealed version.

Encrypted at rest Where it lives What a normal read gives back
Client tax IDs: EIN, SSN, ITIN Account and contact records Last four digits
Bank routing and account numbers Bank account records Last four digits
IRS Identity Protection PIN Contact records Ciphertext at rest
Preparer PTIN and CAF numbers Staff and firm records Ciphertext at rest
OAuth tokens for QuickBooks Online, Xero, a connected mailbox and Anchor Integration connections Never returned, never logged

It fails closed

Without the encryption key, the API returns a 503 and the tax ID doesn't get stored. There's no degraded mode where the number goes in as plain text and somebody fixes it later. The write just doesn't happen.

Where the key lives

It's an Azure Key Vault secret, read at runtime through a managed identity. No copy of it sits on the container app definition, and no engineer has to hold one to run a deploy.

Revealing the full value

One route decrypts a tax ID and one decrypts a bank number. Both demand a fresh identity check first, by passkey, password re-entry or a round trip through your SSO. Without that proof they answer 403. Each reveal writes an audit row recording who and when. The number itself is never in the log.

Rotation, stated precisely

The integration token keys are versioned. Add a new version and it becomes the write key while the older ones stay live to read rows nobody has re-encrypted yet, so a QuickBooks Online or Xero credential key can be retired without asking a firm to reconnect. The key over tax IDs has no versioning. Rotating that one is a migration, not a configuration change, and we'd rather say so than let you assume otherwise.

In transit

TLS 1.2 is the floor. Storage accepts HTTPS only, the container ingress refuses plain HTTP outright, and public traffic terminates at Azure Front Door on managed certificates. The rate limiter keys off the caller IP that Front Door proves, and traffic that tries to reach the origin directly gets rejected instead of counted.

Access

Getting in, staying in, and getting cut off.

Passkeys

WebAuthn, with user verification required. The device has to confirm the person by biometric or PIN, not just prove it's the same laptop. Registration and sign-in both demand it.

Short tokens, rotating refresh

The access token lasts 15 minutes and is held in memory, never in local storage. The refresh token is an opaque value in an httpOnly cookie scoped to the auth routes, and only its SHA-256 hash is kept on our side. It rotates every time it's used. Present a retired one and the whole token family burns, because the only reason to hold a retired refresh token is that somebody copied it.

Sessions you can see

Sessions are tracked per device. Your staff can list where they're signed in and revoke any of it, including everything except the device in front of them. A sign-in from a device we don't recognize sends an email.

Passwords, for the people who use one

Twelve characters minimum, at least three of the four character classes, and a deny-list that strips trailing digits before it checks, so Password1 and Passw0rd2024 both land on the same rejected base. Hashing is bcrypt at cost 12. One module enforces this on registration, reset, set and change, so the rules can't drift apart.

SSO and roles

Microsoft and Google sign-in are both supported, and a firm can claim its email domains so staff arrive through SSO rather than a password. Admin surfaces sit behind an admin check, and self-service edits run against an allowlist that denies any field nobody put on it.

Cutting somebody off

One call revokes every refresh family a user holds, and their access token dies on its own within 15 minutes. Deactivating them also kills their AI-client connections in the same call, not just the browser session. If a firm has to be stopped entirely, suspending it drops every live session in it at once.

Separation between firms

One firm can't read another firm's rows.

Every record in 360 Centric belongs to exactly one firm, and every screen, report, and export is limited to your firm's records before it runs. No individual feature has to remember that rule, because it is applied underneath all of them.

An automatic check runs every time we ship, and fails the release if any new kind of record could slip past that rule. We built it because of the bug it now prevents: early on, one internal report could return another firm's row. Catching the next one before release was worth more than promising it wouldn't happen again.

Behind the check, tests keep proving it: two firms run side by side through the whole test suite, and an automated browser signs into both and confirms neither can see the other.

The audit log

The record only ever grows. The database makes sure of it.

302 kinds of action land in the audit log, across every part of the product: who viewed a masked tax ID, who merged two clients, who deleted a document, who connected an integration, who ran a support session. If a safety control is ever overridden, the override and its log entry succeed or fail together — an unrecorded override can't happen.

The database itself is built to refuse any edit or deletion in that log, no matter who asks — including us. Entries can be added and read, never rewritten, so a bug, a leaked password, or a stray cleanup script can't change what happened.

Your admins read your firm's own trail and can export it, and the export itself gets logged. When our support staff work in your account, everything they do is stamped with their name, and your trail can't be exported during a support session at all. Nothing in the log is ever deleted.

Retention and disposal

What we keep, and how it goes away.

Every stored record type is classified into a retention class or a documented out-of-scope list. A build check refuses to let a model sit in both or in neither, so a new table can't ship without somebody deciding how long its rows live. A record nobody has classified is never eligible for deletion. The fail-safe points at keeping things.

The durations below are starting points drawn from malpractice norms. They aren't legal determinations, and we expect to set them with your firm rather than hand them to you.

Class Default Clock starts
Tax evidence 7 years, a floor Filing or finalization date
Engagement record 7 years Engagement close
Billing and financial 7 years Invoice paid, or commitment ended
Client identity Derived Outlives every other record the client has
Marketing, non-client 1 year Last activity
System log 2 years Event timestamp
Audit log Never purged No clock
Permanent record Never expires No clock

Your firm approves the delete

Expired records collect into a batch. Nothing is destroyed until your firm approves it, or until you've explicitly opted into auto-destroy when a batch lapses. Immediately before each irreversible delete the executor re-runs the whole eligibility check live and withdraws the item if a hold landed, an override was set, or something else still references it.

A legal hold beats everything

A hold on an account is evaluated live, never cached, both by the nightly pass and again inside the delete transaction. A hold that lands between the check and the write still blocks the destruction. Holds are never shown to the client.

Clients get 60 days, then another 60

For documents a client gave you, disposal runs in two stages. The uploading contact gets a co-branded email with a download-by date and a read-only panel in the portal. At day 60 the document is soft-deleted and marked for hard delete at day 120. Pull it back off the track before then and it's restored. Objections route through your firm, because it's your client relationship.

Backups lag by seven days

Automated database backups keep seven days. A row purged from the live database can still sit in a backup until that window ages out. A point-in-time restore doesn't quietly resurrect it either, because the retention pass re-evaluates and re-disposes anything that was already eligible.

Infrastructure and change

Where it runs, and how it changes.

The database and the key store are private

The database and the key store can't be reached from the public internet at all. Only the application can talk to them. Key Vault runs default-deny network rules, keeps soft-delete on a seven-day window, and has purge protection switched on, which is one-way. A boot-critical secret can't be destroyed outright, by us or by anybody else.

No long-lived cloud credentials

Deploys authenticate to Azure over OIDC, so there's no standing Azure secret sitting in a CI settings page waiting to leak. At runtime the app reads its secrets from Key Vault through a user-assigned managed identity, and image pulls use the same identity. The container registry's admin user is turned off.

Secret scanning that can't be quietly disarmed

Gitleaks runs on every pull request across the full commit history, not just the diff, and a finding fails the job. The allowlist has its own guard, because an allowlist is a negative control and a pull request could otherwise silence its own leak. A wildcard entry fails. A path rule too broad to be deliberate fails. If the guard can't parse its own configuration it exits non-zero rather than skipping, and every allowlist entry a pull request adds is surfaced as an annotation on the review.

How a change reaches production

Infrastructure is Bicep, so an environment is a file rather than a memory of what somebody clicked. Every change lands through a pull request, and continuous integration runs typecheck, the test suite and the structural gates on it. Staging deploys on a schedule and on demand. Production is a manual, gated deploy. Scheduled jobs are pinned to the same image as the API on every deploy, so a cron job never runs last month's code.

Migrations are additive

After the baseline, schema changes add rather than remove. A destructive migration needs written approval, a verified backup and a name that starts with DESTRUCTIVE_, which makes it impossible to merge one by accident or to miss it reading a file list.

Dependencies

Dependabot opens update pull requests weekly, and they go through the same checks as anything else. A dependency CVE with no evidence of exploitation is a normal engineering fix on a normal timeline, and the incident plan says so rather than pretending everything is an emergency.

Monitoring and incidents

When something looks wrong.

Errors go to Sentry with default PII collection off, and a scrubber runs before anything leaves the process. It strips auth headers, cookies and request bodies, redacts any key shaped like a token, secret, password or tax ID, and masks secret-shaped values that ride along inside a free-text message. No tax ID, bank number or request body reaches Sentry. Application and infrastructure logs stay in Azure Log Analytics on a 365-day window.

The remote AI-assistant surface has its own tripwire. When one connection pages through a large share of a firm's accounts or contacts, that's the read-only exfiltration signature, and it raises a throttled alert carrying connection IDs, organization IDs and counts. No names, no emails, no row data. Scheduled jobs report to cron monitors, so a run that fails or never starts alerts rather than going unnoticed until somebody asks why a digest didn't arrive.

Containment steps are written down, and every one maps to a code path that already ships. Revoke one user's token families. Sign one device out. Deactivate a user and take their AI-client connections with them. Suspend a firm and drop every live session in it. A platform admin can't suspend their own firm, so an isolated operator can't lock themselves out mid-incident.

What we commit to telling you

If we confirm a breach touching your firm's data, your designated contact hears from us within 72 hours of that confirmation, with what we know at that moment even if the scoping is still running. An early partial account beats a complete one that arrives after your own clock has started. The per-firm scoping output follows as soon as it's ready, and then the root cause and what we changed.

Who runs an incident here

One person holds all four incident roles today. The plan names them separately anyway, so the day a second pair of hands arrives the work splits along lines that already exist instead of being invented mid-incident. You should know the size of the team standing behind that 72 hours.

Subprocessors

Everyone else who touches the data.

Ten vendors, and here they all are. Several only apply if your firm switches on the feature that uses them. Where a data-processing agreement is still open we say pending, rather than leaving the vendor off the list and hoping nobody asks.

Subprocessor What it does for you Region Data agreement
Microsoft Azure Hosting, the database, document storage, the secret store, the TLS edge, infrastructure logs. East US 2 Microsoft Products and Services DPA
Anthropic Reading and classifying documents, when your firm switches it on. It suggests and a person confirms. It never writes to a client record on its own. United States Pending
Postmark Every transactional email we send, including the co-branded notices that go to your clients. United States Published standard DPA
Sentry Error monitoring. It receives scrubbed error events and nothing else. United States Pending
Google Optional staff sign-in, when someone chooses Google. Global Google OAuth and Cloud terms
Microsoft Entra and Graph Optional staff sign-in, and mailbox sync for the people who connect a mailbox. Your Microsoft tenant Microsoft Products and Services DPA
Intuit The QuickBooks Online read, for each company you authorize. United States Intuit Developer terms
Xero The Xero read, for each organization you grant. Global Xero developer terms
Anchor Client commitments and billing records, for firms that connect it. Vendor SaaS Anchor API terms
Didit The remote identity check before a Form 8879 signature, when a taxpayer isn't in front of you. Off unless your firm turns it on. Vendor SaaS Pending

Anthropic

The AI reading of documents is off unless a firm enables it. Anthropic's commercial terms already say inputs and outputs aren't used for training, and zero data retention is available.

Sentry

The agreement is the last open item on our logging backlog. It's worth noting what Sentry actually receives, which is scrubbed error events. The logs themselves stay in Azure.

Didit

Used only for the remote identity check before a Form 8879 signature, and only when a firm enables it. ID images and liveness capture stay with Didit. We keep the decision, the session ID and the consent stamp, not the media.

Azure Communication Services was retired as an email provider and removed from the code. Postmark is the only sender. Regions above are as each vendor states them, and this register describes who we use rather than forming any agreement between your firm and them.

FTC Safeguards Rule and IRS Pub. 5708

How this lands in your WISP.

Your Written Information Security Plan is your document about your program. We're one service provider inside it, not a substitute for it, and no software makes a firm compliant. What we can do is put the evidence where your Qualified Individual expects to find it, so the service-provider section of the plan takes an afternoon instead of a month of emails.

This table is informational. It isn't legal advice and it doesn't certify that using 360 Centric satisfies any particular requirement. Confirm that with your own advisor.

What your plan has to speak to Where the evidence is
Identify your service providers, and reassess them periodically. 16 CFR 314.4(f) This page and the subprocessor list above. Print it and it goes in the vendor file.
Risk assessment and data inventory. 314.4(b), (c)(2) The encrypted-field table says which fields hold ciphertext and what a normal read gives back. The retention classes say what we keep and for how long.
Encrypt customer information at rest and in transit. 314.4(c)(3) AES-256-GCM over tax IDs, IP PINs, bank numbers and integration tokens. TLS 1.2 as the floor. Keys held in Azure Key Vault and read through a managed identity.
Access controls and authentication. 314.4(c)(1), (5) Passkeys with user verification required, 15-minute access tokens, rotating refresh tokens that burn the family on reuse, per-device sessions, a second identity check before any reveal, SSO, role gating.
Keep one firm's data separate from another's Firm-level separation applied underneath every feature, the release check that keeps it complete, and the cross-firm tests behind it.
Log and monitor activity. 314.4(c)(6), (d) The append-only audit log your admins read and export, plus error monitoring, sweep alerts on the AI-client surface, and new-device emails.
Secure development and change management. 314.4(c)(2) Infrastructure as code, structural checks that fail the build, a manual gated production deploy, locked migration rules. Read the branch-protection note further down.
Secure disposal. 314.4(c)(6) Retention classes, destruction your firm approves, the 60 and 120 day client window, a legal hold evaluated live, and the seven-day backup lag stated plainly.
Your own breach-notification clock Our 72-hour commitment and the per-firm scoping output are what start yours, so you're not waiting on us to find out what happened.

A note on the notification thresholds your own counsel will ask about. The FTC Safeguards Rule requires a covered firm to report a notification event affecting 500 or more consumers, and state statutes set their own deadlines on top. Many accounting and tax firms fall inside the FTC's definition of a financial institution. Verify the current text before you rely on any of it, because the rule has been amended before.

Bring the questions your IT reviewer would ask.

We'll walk the reveal flow, the audit log and the retention screens in the demo, including the parts that aren't finished. Nothing on this page gets softer when you're on the call.