Skip to main content

Owner Guide — Producing Extracts for a Flat File Source

What an application owner needs to know to produce the account and entitlement CSVs that feed a disconnected (flat file) source in ISC. It is written for the person who runs the extract, and for the owner who signs off on it.

If you're reading this, you likely own one of the ~50 manual-fulfillment applications being migrated from Courion to SailPoint Identity Security Cloud. Your job in the new model is to produce a regular snapshot of who has what access on your system: what data to send is this page and the File Specification; how to send it is Delivery Options.

Everything here comes from the systems actually onboarded or staged in capriiam-qa — SalesAudit, Hyperion, Hyperion Planning, MicroStrategy, SFCC, and WebFocus — and from what building them taught us. This page is the contract for the files themselves; the formal reference an extract developer builds against — exact schemas, column order, allowed values, validation rules — is the File Specification.

The two files, and the difference between them

Every source is fed by two CSVs with two different jobs:

Account fileEntitlement file
AnswersWho has access, and what they holdWhat each access value means
One row perAccount in the applicationDistinct entitlement (group, role, permission)
Typical sizeHundreds to thousands of rowsTens of rows
Upload semanticsFull snapshot — an account missing from the file is deleted in ISCCatalog — describes and decorates, does not grant
If it is wrongPeople gain, lose, or keep access incorrectlyRequesters and certifiers approve things they cannot understand
Load orderSecondFirst

The account file is the record of access: each row is one login in your application, and the groups column lists the entitlement IDs that account holds. The entitlement file is the dictionary those IDs resolve against: display name, description, owner, and the flags that control whether something can be requested and how it is certified.

They meet on one rule: every value in the account file's groups column must appear as an id in the entitlement file. The build validates this and fails on any orphan, because an entitlement that arrives only via an account row aggregates as a bare value — no description, no owner, nothing a certifier can act on. (Entitlements defined but held by nobody are allowed; they just produce a warning.)

Entitlements load first for the same reason: accounts loaded before their entitlements exist arrive holding bare references.

The account file

The layout used by every source built so far:

id,name,employeeId,givenName,familyName,e-mail,location,IIQDisabled,groups
JDOEJC,Jane Doe,123456,Jane,Doe,jane.doe@example.com,"Milan, IT",false,JC_HFM_Submitter_Americas;JC_HFM_Viewer_UK;JC_HFM_Viewer_Italy

(Example rows on this page are anonymized.)

ColumnWhat it must be
idThe account's unique identifier in your application — login name, username, whatever the application keys on. Required on every row; a blank or missing id fails the file.
nameHuman-readable display name for the account.
employeeIdThe correlation key. This is how ISC ties the account to a person — see below.
givenName / familyNameFirst and last name.
e-mailThe account's email address. Note the hyphen in the header: e-mail, not email — column names are validated exactly. Informational — it is not used to match the account to a person.
locationFree text. Quote it if it contains commas: "New York, NY, US".
IIQDisabledtrue if the account is disabled in your application, false otherwise — see Leavers.
groupsThe entitlement IDs this account holds, separated by ; — see below.

employeeId is what connects an account to a person

ISC correlates each account to an identity by matching employeeId against the HR record. Email is deliberately not the key — addresses churn on name changes and differ across brands.

  • A row without an employeeId loads, but correlates to nobody: it belongs to no identity, appears in no certification of that person's access, does not respond to joiner/mover/leaver events — a leaver's termination never reaches it — and surfaces in audit reports as an exception. Some populations (contractors, service accounts with no HR record) are known and accepted gaps for specific sources — but that is a per-source decision, not a default. Tell us about every population you cannot supply an ID for.
  • Several accounts sharing one employeeId is fine and correct. Some people hold logins in more than one brand's instance of the same application; both rows carry the same employee ID and both correlate to the same person.
  • A fallback correlation on e-mail may be configured for populations that genuinely have no employee ID — but the design assumes employeeId is the key; the fallback is an agreed exception, not a substitute.
  • During your first days of onboarding, a small number of uncorrelated accounts is expected while correlation rules are tuned. Long-term uncorrelated accounts become audit findings.

Multiple entitlements in one cell

More than one entitlement on an account is expressed as a single groups cell with values separated by ;:

JDOEJC,Jane Doe,...,JC_HFM_Submitter_Americas;JC_HFM_Viewer_UK;JC_HFM_Viewer_Italy

This works because the upload pipeline expands each such row into one row per entitlement before ISC sees it. (That expansion belongs to the file-drop pipeline — a team pushing via the API directly does it themselves; see Delivery Options.) It is not optional decoration — the connector itself cannot split a cell, and a file loaded without the expansion produces entitlements literally named JC_HFM_Submitter_Americas;JC_HFM_Viewer_UK;JC_HFM_Viewer_Italy. That happened on a real build once: concatenated entitlements sat in the tenant for a week looking healthy. So:

  • Use ; consistently, with no stray spaces around it.
  • Never use ; inside an entitlement ID or name.
  • If your export tool aggregates with a different character, say so before the first delivery — the delimiter is configured per source, not guessed.

Every delivery is a full snapshot

ISC deletes any account that is absent from the file. There is no delta mode. This has two consequences:

  1. Every extract must contain the complete account population, every time. A truncated or partial file silently deletes the missing accounts, and the deletions cascade into role membership and certification history.
  2. A "changed since last run" export is never acceptable. If your tooling can only produce deltas, stop and tell us — that is a design conversation, not a formatting fix.

Row count is the sanity check on both ends: know roughly how many accounts your system has, and flag any extract that deviates sharply.

Leavers: disabled is a column, not a missing row

When someone leaves or an account is disabled, the row stays in the file with IIQDisabled set to true. Dropping the row instead looks like success and is the single most damaging mistake a producer can make: ISC records the account as deleted, and with it goes the evidence it was ever disabled, the certification history, and anything an auditor would attest against.

IIQDisabled is read as a string, so true, false, and an empty cell are three different values. The convention is literal lowercase true / false on every row — pin your export to that and do not vary it.

The entitlement file

The layout used by every source built so far:

id,name,displayName,description,owner,requestable,privileged,entitlementType
HFM_Admin,HFM_Admin,HFM Administrator,"Full administrative control over the HFM application…",sam.roe@example.com,false,true,Financial Consolidation
ColumnWhat it must be
idThe entitlement's identifier — exactly the string that appears in the account file's groups column, case-sensitive. Must be unique within the file; duplicates fail validation.
nameUsually the same as id.
displayNameWhat requesters see in the access catalog. Write it for a human: Jimmy Choo HFM Submitter - Americas Entities, not JC_HFM_SUB_AM.
descriptionWhat this access actually lets someone do — see below.
ownerEmail of the person accountable for this entitlement — see below.
requestabletrue if users may request it through self-service; false keeps it out of the catalog.
privilegedtrue for admin-level access — sorts it to the top of certifications and into privileged-access reporting.
entitlementTypeA category of your choosing (Financial Consolidation, Display Preference, Platform Administration…). Kept as a searchable attribute and usable in access profile filters.

Descriptions are read by approvers and certifiers

The description is what a manager sees when deciding whether to approve a request, and what a certifier sees when deciding whether someone should keep access. Say what the access permits and flag what makes it sensitive — for example, note when access is SOX-relevant financial access, or carries access to customer PII. Descriptions are truncated at 2,000 characters; well before that limit, shorter and concrete beats exhaustive.

The owner column must name a real person in ISC

The entitlement owner is not decoration: manual provisioning tasks route to the entitlement owner (with the source owner as fallback), and certifications may be assigned by owner. Two hard-won rules:

  • The address must resolve to an identity in the ISC tenant. Your directory and the tenant are not the same thing — an extract once named an owner address on every entitlement that matched nobody in the tenant. Nothing in your export tooling will catch this; it surfaces weeks later as provisioning tasks routed to nobody.
  • The owner must be a monitored mailbox/identity — a person who will actually see and act on the tasks routed to them.

When an owner cannot be resolved, we override it in the source's configuration rather than editing your file, so send the value you believe correct and expect a conversation if it does not resolve.

requestable and privileged are governance, not description

Both flags are invisible when wrong, and both matter on day one:

  • requestable: false is what keeps an admin role out of the self-service catalog. Left defaulted, an admin role is one request away from anyone.
  • privileged: true changes who scrutinizes the entitlement — certification ordering and privileged-access reports — without changing any permission by itself.

These columns (with owner) are applied through the ISC API after the load rather than stored as attributes of your application — but that is our mechanics, not yours. Supply them in the file; the pipeline knows which columns are governance and which are schema.

Format rules

RuleDetail
EncodingUTF-8. A leading byte-order mark is tolerated.
Header rowRequired, exact column names as shown above — they are validated against the source schema.
QuotingStandard CSV quoting. Any value containing a comma must be quoted: "Milan, IT". Real CSV libraries do this for you; hand-built exports get it wrong.
Row shapeEvery row must have the same number of columns as the header. Ragged rows fail the file.
Forbidden charactersNo emojis, no + in values.
Size limitsAccounts: 500 MB / ~400,000 rows per file. Entitlements: 1 MB.
SortingAccount files sorted by account id.

Every delivered file is validated before anything touches the tenant — header present, id column present and populated, no ragged rows, unique entitlement IDs, every referenced entitlement defined. A file that fails is rejected whole; nothing partial is loaded.

Delivery and cadence

  • Agree a cadence and keep it. ISC only learns about changes in your application when a file arrives — the file is the aggregation. A weekly extract means access changes, leaver disables, and unauthorized-change detection all run on a weekly clock, no matter what is configured elsewhere.
  • Send the file as produced. We keep your file byte-for-byte as delivered and make any corrections (owner overrides, delimiter handling, column ordering) in configuration on our side, where they are reviewable and survive the next delivery. A hand-edited file just means the next extract silently disagrees with the last one.
  • Same layout every time. Adding, removing, or reordering columns is a schema change on the ISC side — coordinate it before the extract changes, not after.

See What Happens After You Send a File for how the file's contents surface to the people requesting and approving access, and Refresh Cadence and Delivery for what "agree a cadence" means in practice.

Transport: the ESB file share, encrypted

The default delivery is a file drop to the SailPoint ESB file share — account and entitlement CSVs are never accepted by email or ad-hoc channels. Teams with existing automation can instead push directly to the ISC API; the file format is identical either way — see Delivery Options for both paths, the credentials involved, and what happens when a delivery is rejected.

Every file dropped on the share must be encrypted with the ESB public key. An unencrypted file, or one encrypted with the wrong key, will not be picked up.

Contact Dharani Kanker to get set up: obtaining the ESB public key, access to the file share, and the exact drop-off path for your source.

Checklist before sending

  1. Complete population — every account, including disabled ones. Row count in the expected range.
  2. Terminated/disabled users present with IIQDisabled set to true, not dropped.
  3. Every employeeId populated, or the exceptions known and agreed.
  4. Every value in groups exists as an id in the entitlement file.
  5. Multi-valued groups cells use ;, and no entitlement name contains ;.
  6. Entitlement ids unique; every entitlement has a display name, a description, and an owner who is a real, monitored person in the tenant.
  7. requestable and privileged reviewed — is anything admin-level requestable by everyone?
  8. UTF-8, quoted commas, no ragged rows, header exactly as specified.