Endpoints
This section covers all endpoints exposed by the Grey Matter Data API and their functionality.
/config
Get basic config information about the server, needed by apps to make decisions about setting up the UI
Request parameter
Parameter Value
There are no parameter values. But we get back config. This is an example of a system configured so that "/world" is the home directory where we are allowed self-service home directory creation. And in here, this directory must be named after an email that shows up in your JWT token. This /config
Says that creating a home dir /world
with parentoid: "42"
is allowed if the directory name is equal to an email value from jwt. So, we propose to write an object with at least these fields,
Normally, a
parentoid
is just a numeric identifier for a directory (likepwd
). It is now possible when doing updates to specify subdirectories like42/books
for a file to go into. If that directory does not yet exist, it will be created. But note that because it is perfectly permissible in gm-data to have multiple directories with the same name but a different oid, this may sometimes create an unwanted result where the user has to merge the directories together. This feature exists mostly for the sake of bulk upload scenarios, where it can be too painful to have to ensure that every directory exists beforehand. This can be the case when the directory is cut up by dates to keep directory size small in the face of a massive number of files being uploaded. ie:42d335/collects/2013/02/03
as aparentoid
And the JWT claims assert at least
This write would be allowed, because the JWT does have an email with the name we are trying to write. So, we can create the directory /world/bob.null@email.com
. This is an example of a "self-service" home directory, so that administrators do not need to get involved in users having a home directory to write into, because their userid, email in this case, is asserted. So /world/${email}
is safe for this user to write into.
/read
Read endpoint allows for bulk querying of Grey Matter Data.
Request parameter
Parameter Value
URL
{host}/read
body
stringified( [{URL: '/list/${id1}/'}, {URL: '/list/${id2}/'}, {URL: '/props/${id1}/'}] )
method
POST
credentialsInclude
true
Query Strings
While query strings may not be applied to the /read
endpoint directly, they may be applied to the URL parameters passed in the body of the request. An example stringified body of the request with query strings is presented below in JavaScript:
Common use cases
File structure exploration, through bulk requests of the
/list
endpoint,Unifying requests to reduce network traffic or improve performance on slow connections. For example, through bulk requests of
/props
endpoint data or/stream
of Object thumbnails for an entire or part of a folder, andPre-loading deep file structure to improve user experience and speed of navigation on fast connections, through bulk requests of
/list
endpoint with each subsequent call requesting a whole level deeper info file structure to pre-load user selection.
/read JavaScript example
/props
Props endpoint returns the latest Event Object on an Object ID. Specifying ?tstamp=
query parameter will return the latest Event Object as of that time.
Request parameter
Parameter Value
URL
{host}/props/{oid}/{path}?queryString1=queryValue1
body
none
method
GET
credentialsInclude
true
/props Query Strings
Query String
URL Example
Description
?tstamp
{host}/props/1578cfdd0241cbee/?tstamp=1578a72437e23c00
?tstamp may be must be specified in 64-bit hex (Unix Nanoseconds)
/path/
{host}/props/1578cfdd039b919b/testFolder/TestFile.csv
/path/
may be added, composed of names, which is an Object property, and separated by a /, which will be internally converted to Object IDs to construct a full path to desired file. This is necessary to allow deep linking into the system.
/props Common use cases
Getting information about an Object
Exploring Object's versions by specifying different time stamps
/props JavaScript example
/list
List endpoint gets latest Event Object of each child Object IDs. Use this method to explore folders and navigate through file structure. This method will return an error if used on a file (no Event Objects in the system have this Objects ID in the parentoid
parameter).
Request parameter
Parameter Value
URL
{host}/list/{oid}/{path}/?queryString1=queryValue1&?queryString2=queryValue2
body
none
method
GET
credentialsInclude
true
/list Query Strings
Query String
URL Example
Description
?childCount
{host}/list/1578cfdd0241cbee/?childCount=true
?childCount
to count the children in each subdirectory
?tstamp
{host}/list/1578cfdd0241cbee/?tstamp=1578a72437e23c00
?tstamp
may be must be specified in 64-bit hex (Unix Nanoseconds)
?last
{host}/list/1578cfdd039b919b/?last=1578cfdd0241cbee&count=10
?last
may be added, as an Object ID, (tstamp for /notifications and /history) used in conjunction with ?count to control paging. Specify Object ID last seen as a cutoff.
?count
{host}/list/1578cfdd039b919b/?last=1578cfdd0241cbee&count=10
?count
may be added, used in conjunction with ?last to control paging.
/path/
{host}/list/1578cfdd039b919b/testFolder/TestFile.csv
/path/ may be added, composed of names, which is an Object property, and separated by a /, which will be internally converted to Object IDs to construct a full path to desired file. This is necessary to allow deep linking into the system.
/list Common use cases
Exploring file structure of the system.
/list JavaScript example
/history
Gets all Events associated with an Object ID.
Request parameter
Parameter Value
URL
{host}/history/{oid}/{path}?queryString1=queryValue1
body
none
method
GET
credentialsInclude
true
/history Query Strings
Query String
URL Example
Description
?tstamp
{host}/history/1578cfdd0241cbee/?tstamp=1578a72437e23c00
?tstamp
may be must be specified in 64-bit hex (Unix Nanoseconds)
?last
{host}/notifications/1/?last=1578a72437e23c00&count=10
?last
may be added, as a timestamp (for /notification and /history, but oid for /list) used in conjunction with ?count to control paging. Specify Object ID last seen as a cutoff.
?count
{host}/notifications/1/?last=1578a72437e23c00&count=10
?count
may be added, used in conjunction with ?last to control paging.
/path/
{host}/history/1578cfdd039b919b/testFolder/TestFile.csv
/path/
may be added, composed of names, which is an Object property, and separated by a /, which will be internally converted to Object IDs to construct a full path to desired file. This is necessary to allow deep linking into the system.
/history Common use cases
Getting version history of an Object,
Polling this endpoint with Object ID specified to have notifications, and
Collecting system-wide analytics by querying this endpoint without inputting an Object ID.
/history JavaScript example
/stream
Gets raw bytes of an Object ID.
Request parameter
Parameter Value
URL
{host}/stream/{oid}/{path}/?queryString1=queryValue1&?queryString2=queryValue2
body
none
method
GET
credentialsInclude
true
/stream Query Strings
Query String
URL Example
Description
?tstamp
{host}/stream/1578cfdd0241cbee/?tstamp=1578a72437e23c00
?tstamp
may be must be specified in 64-bit hex (Unix Nanoseconds)
/path/
{host}/stream/1578cfdd039b919b/testFolder/TestFile.csv
/path/
may be added, composed of names, which is an Object property, and separated by a /, which will be internally converted to Object IDs to construct a full path to desired file. This is necessary to allow deep linking into the system.
?disposition
{host}/stream/41312434423/file.txt?disposition=attachment
The Content-Disposition
header defaults to inline, so that browser shows the file. Use disposition=attachment
to force a browser download.
Standard HTTP range requesting is supported on streams. Browsers will range request large media files without any special usage of the API
This endpoint can take range requesting parameters as well.
rangeLow
andrangeHigh
are the upper and lower bound on bytes to be retrieved out of the stream.rangeHigh
can be omitted, to get an open-ended stream that runs until the file ends.rangeLength
is an alternative to usingrangeHigh
, to specify the desired content length of the partial download directly. Units are allowed on these.k
,m
,g
,t
are recognized.k
is a unit of 1024 - computer kilobyte, etc. Notice that as required in the http range request specification, therangeHigh
turned into an actual number (with units multiplied in) is the location of the last byte in the data that comes back; which is probably one less than you may expect. ex: bytes=0-1023 asks for 1024 bytes. bytes=1k-2k also asks for 1024 bytes. If there is a unit on the upper-bound, then the number has 1 subtracted from it to be rendered the way that http wants it.
/stream Common use cases
Downloading Objects locally.
/stream JavaScript example
/show
Gets raw bytes of an Object ID and wraps it in an iFrame that shows Objects security meta data.
Request parameter
Parameter Value
URL
{host}/show/{oid}/{path}/?queryString1=queryValue1
body
none
method
GET
credentialsInclude
true
/show Query Strings
Query String
URL Example
Description
?tstamp
{host}/show/1578cfdd0241cbee/?tstamp=1578a72437e23c00
?tstamp
may be must be specified in 64-bit hex (Unix Nanoseconds)
/path/
{host}/show/1578cfdd039b919b/testFolder/TestFile.csv
/path/
may be added, composed of names, which is an Object property, and separated by a /, which will be internally converted to Object IDs to construct a full path to desired file. This is necessary to allow deep linking into the system.
/show Common use cases
Preview Object in browser, and
Serve stored assets to remote clients in a CDN-like manner but with fine grained security policies.
/show JavaScript example
/macros
An internal method used for verification of Object’s security policy.
Request parameter
Parameter Value
URL
{host}/macros/{oid}/
body
none
method
GET
credentialsInclude
true
/lisp-to-json
POST object policy lisp here to convert it to json, so that you do not need a port of the converter to your language
Request parameter
Parameter Value
URL
/lisp-to-json
body
object policy in lisp format
method
POST
Limited to 5MB POST body
/json-to-lisp
POST object policy lisp here to convert it to json, so that you do not need a port of the converter to your language
Request parameter
Parameter Value
URL
/json-to-lisp
body
object policy in json format
method
POST
Limited to 5MB POST body
/json-to-lisp Query Strings
none
/json-to-lisp Common use cases
Verify Objects security policy complies with security schema.
/macros JavaScript example
/notifications
Returns all events for specified Object ID
Request parameter
Parameter Value
URL
{host}/notifications/{oid}/
body
none
method
GET
credentialsInclude
true
/notifications Query Strings
Query String
URL Example
Description
?tstamp
{host}/c/1578cfdd0241cbee/?tstamp=1578a72437e23c00
?tstamp
may be must be specified in 64-bit hex (Unix Nanoseconds)
?last
{host}/notificationsQueryStrings/1578cfdd039b919b/?last=1578a72437e23c00&count=10
?last
may be added, as a timestamp (for /notification and /history, but oid for /list) used in conjunction with ?count to control paging. Specify Object ID last seen as a cutoff.
?count
{host}/notificationsQueryStrings/1578cfdd039b919b/?last=1578a72437e23c00&count=10
?count
may be added, used in conjunction with ?last to control paging.
/path/
{host}/notificationsQueryStrings/1578cfdd039b919b/testFolder/TestFile.csv
/path/ may be added, composed of names, which is an Object property, and separated by a /, which will be internally converted to Object IDs to construct a full path to desired file. This is necessary to allow deep linking into the system.
/notifications Common use cases
Get all changes to the system for monitoring purposes when requesting notifications from root directory
Get notifications for a specific folder in the system to keep track of updates
/notifications JavaScript example
/derived
Returns list of Object IDs of files that are related to specified Object ID
Request parameter
Parameter Value
URL
{host}/derived/{oid}/
body
none
method
GET
credentialsInclude
true
/derived Query Strings
none
/derived Common use cases
Find all Objects that are related to another Object, for example, thumbnails of an image.
/derived JavaScript example
/write
Write endpoint is the only way to modify data within Grey Matter Data. Requests sent to /write
endpoint must use POST
and have form data in the body of the request, container ‘meta’ property with an Event Object. In case of file upload, form data must also have ‘blob’ property with file in Blob format attached.
Request parameter
Parameter Value
URL
{host}/write
body
form data
method
POST
credentialsInclude
true
Note: The root directory of a freshly initialized system is read only. The system will be configured with a root directory with self-service permissions. Usually, this directory will be called
/world
, and will allow you only to create a directory named after yourPOST /write
call). It is possible that this can be re-configured to be something else (/home
,/northeast
) for the directory name, and possibly a different field that is signed in the user's JWT token (ie:username
,dn
,cn
, etc.). Within this directory that you are allowed to create, you can have whatever permissions you want. This ensures that the root directory has a regular structure that UIs can predict, and is not filled with testing garbage.
/write Query Strings
none
/write Example JavaScript FormData with an Event being appended
In this example, we have a simple update in which we are not worried about losing any other fields other than the ones mentioned. See the next example of how updates and deletes should normally be done.
/write Example JavaScript of updating a file name
Note: when action: 'U' (update) is specified, all parameters, except the few that are being updated and tstamp
, must be specified, mimicking previous Event associated with the Object ID that is being updated.
An update or delete will need to preserve previous values. So, get a copy of the previous /props
for this oid. Then submit a modification of it with these changes:
action must be
U
you can modify fields other than
oid
by default, if you leave the field
rname
in, it will not update the file, but only its properties.rname
is the random name assigned to the file blob that is (usually) stored in S3.if you blank out
rname
, then the formData will insist that you append the file. you are telling the system "do not use the existing blob, use one created from this file instead".
For all updates and deletes, start with the existing obj from
/props/{oid}/
as a template. Modify action, then the desired fields that need to change. Wheneverrname
is blanked out on a create or update, the formData must supply a blob for it.
/write Example JavaScript of upload 2 files
In case of data upload, a request’s form data must have an appended {'blob': File BLOB}
object for each file that is being uploaded in the same order as specified in the accompanying meta Event object. More information on this can be found in the /write
endpoint section.
Updates In General
In order to update an object, the strategy is to:
Get the most recent item as an example and submit a modification to it
The
/props
for this oid, or first entry of/history
will be the most recent state.Many fields from this version were written by the server, and will be ignored if we leave them set. So we can ignore some of these fields for example:
tstamp
tstampend
jwthash
checkedtstamp
Just take the most recent state and submit a modification
Any field other than
oid
can be updated (if it's not one of the ignored fields)
Set action to
U
if we plan on making an updateIf we plan on altering the file stream, then we must remove the field
rname
. What this means is "I am not going to reference an existing random name to an already uploaded stream. I am going to supply you with a new stream (which will be assigned its own rname.).If we just want to modify properties and not update the stream, then
rname
should be left where it is.You can use this functionality to pick an older
rname
in history to revert back to an older stream. But note that you cannot use anrname
from another oid, as the oid is part of what determines the encryption key for the object.Set an action to
D
if we plan on doing a delete. Note that the fields on this deleted object determine what it will look like in the trashcan. If it is resurrected from the trashcan by re-submitting with aU
, then all fields (including recentrname
) must be present.
If an object is already in state
D
, then it is eligible for a purge by setting the action toP
. A simpleP
will remove the entire object oid from the database, and leave a temporary purge marker (for replication reasons) that will expire shortly. If the metadata about the purged file is sensitive, then all such fields can be redacted when writing the purge object. For example, set thename
andobjectpolicy
(possibly every property) to redacted values. This file can not be resurrected from the trash, and the only thing really needed of it is theoid
.fulldir
is a fully qualified directory that this item is in, at the time of the update. It must include the root oid, and terminate the fulldir (of the parent only) with a slash. If you want to be able to filter like: "everything under /0000000000000001/home/rob/", then setfulldir
on objects as they are updated. Since we locate objects like(oid, name)
, this does not give you an easy way to know that an oid happens to be under another oid. So, for efficiency reasons, we leave this task to the client; who knows the full path to every object being written. Example:/aae8f90aef/home/rob/
has a directory with namework
. Thefulldir
is the directory that this object is in:/aae8f90aef/home/rob/
, even thoughwork
is itself a directory. The path for this object, that happens to be a directory (isfile=false
), is:/aae8f90aef/home/rob/work
. So to list thework
dir, the full dir is:/list/aae8f90aef/home/rob/work
/aae8f90aef/home/rob/
also has a file namedresume.pdf
. So,fulldir
is/aae8f90aef/home/rob/
, but stream the data with:/stream/aae8f90aef/home/rob/resume.pdf
Security Caveats:
If you made a permissions mistake, then fix it with
action: P
; asaction: D
is an update with hide. The default system assumes that permissions mistakes are not being made, so performing a D on a file hides it from current version, but allows historical versions to be retrieved using/history
and thetstamp
parameter; like a delete from a version control system. If there was a permission mistake, thenaction: P
the file to purge the entire file (redacting fields as necessary, for theaction: P
entry will remain in the database for a while), or include thepurgetstamp
to just purge one mistaken state (ie: an update with a wrong classification applied to it). This will keep it out of the database, but such records may have already escaped on Kafka queues.With Update permission (from CRUDXP), you effectively have full access to the file. If you have permission
U
on a file to update it, you can use this to make updates to grant all the other privileges on that file. So as far as enforcement goes,(R, X, U)
are the main privileges.D
andP
show up as extra privileges to advise what the policy is supposed to be; and to stop accidents. This is a similar issue withchmod
andchown
under Unix. You may not have execute bits on a Unix file, but if you havew
access, then you can grant it to yourself.If a bot writes a file on behalf of another user, the bot will need read and update access on the file. If you attempt to perform a write, without at least
(R,U)
access, you will not be able to correct any mistaken writes. So, the system will warn you that you may be trying to use wrong permissions (perhaps a misspelled role, attribute name, email,or userDN). But a bot may well try to write a file that it does not have permissions to update or read later. It is inadvisable to useallowpartialpermissions
to make the write go through; because if the write succeeds with the permissions in error, then there is now data in the system to which NO user has access. It's technically possible to generate(contains privilege root)
tokens that ignore permissions, but it's likely that your admin will not allow it, or help you to issue such tokens. Thus, there would be no way to clean up messes created by users writing things that they cannot edit themselves. So, it's best to make a write succeed by making sure that the author of the write has(R,U)
privileges.
In this section we reviewed every endpoint provided by the Grey Matter Data API and the purpose it serves. Through combinations of endpoints and query strings, you will have complete, fine-grained control of your data.
/self
Reflect back the JWT claims that had been signed, that the server believes to be true due to the signature. The result is json.
Last updated
Was this helpful?