Table of Contents

Document Security

Document Security is an optional feature that can be enabled using the model editor. It adds an authorisation layer to document operations. Without this feature enabled, all authorised users can access all documents if they know the ID of the document they want to retrieve.

Model

Enabling this feature adds one entity to the model: DocumentAccessEntry. This entity represents one document access rule.

Access Rules

The presence (or absence) of access rules controls access to a document.

  • A document can have any number of access rules.
  • An access rule can grant access to a document either globally or through a particular entity.
  • If a document has no access rules, it is by default not accessible.
  • A principal that has access to a document can:
    • download it and its metadata,
    • upload thumbnails (in the case of images), and
    • create additional access rules for that document.
  • Users with the AccessAllDocuments flag or the admin permission can access all documents regardless of access rules or their level of access to particular entities or tenancies.

Interacting with documents when using document security

When accessing a document, the caller must provide a DocumentAccessAssertion to describe how they have access to it, which comes in two forms:

  • EntityDocumentAccessAssertion meaning that the caller asserts that an EntityDocumentAccessRule exists for that document and that the caller can access the entity described by the rule.
  • UnspecifiedDocumentAccessAssertion meaning that the caller has some implicit permission to access the document, such as via a GlobalDocumentAccessRule, DocumentOptions configuration, user flags or admin permission.

When uploading a document, the caller must provide a DocumentAccessRule describing a rule for accessing that document, which comes in three forms:

  • EntityDocumentAccessRule which refers to a particular entity and attribute by IDs, plus a NewEntity flag. Principals must provide a matching EntityDocumentAccessAssertion with the same IDs to be able to access a document using this rule, need to be able to read the entity described by the IDs, and the entity must exist for that principal.
    • If the NewEntity flag is specified it means that the document has been uploaded to be associated with a new entity that hasn't yet been saved. Document security allows some leeway for accessing a document uploaded in this way (a configurable period of 10 minutes by default and only from the uploading principal) before requiring that the entity exists.
  • GlobalDocumentAccessRule which allows any authorised user to access the document.
  • UnspecifiedDocumentAccessRule which means no rule should be added.

Internals

Document authorisation is handled by AuthorisingDocumentStore, a new IDocumentStore wrapper that is constructed automatically when composing the instagile framework.

When saving an entity, new access rules will first be created for any documents that may have been copied into that entity. If the context is not authorised to create those rules (due to not having access to the document it is attempting to copy) then the save will fail before any entity persistence operations are executed.

Enabling document security in an existing application

If an application has existing document data without having this feature enabled, then document rules need to be created before the feature is usable.

The backend job DocumentSecurityMigrationJob can scan the database for documents and create rules for all of them. By default, this job will block startup and attempt to create an EntityDocumentAccessRule for every not null document attribute in every entity in the database, so long as no rules already exist. The job can be configured using the configuration object DocumentSecurityMigrationOptions.

If the migration would take too long, it can be configured to not block startup by disabling BlockStartupUntilComplete. Developers may also want to enable DocumentOptions.DefaultGlobalAccess so that users can access documents without an access rule while the job is running.

If the job is interrupted it will not be able to resume unless the option AbortIfAnyRulesExist is disabled, or all rules are purged. If this option is disabled, the job will run slower because it will need to check if particular rules exist before creating them.