permify icon indicating copy to clipboard operation
permify copied to clipboard

Modification timestamps in data APIs

Open pete-woods opened this issue 10 months ago • 2 comments

Is your feature request related to a problem? Please describe. To be able to show when a relationship was created (or indeed an attribute added/modified) is very useful when creating management APIs/UIs in your application.

This gives administrators an "at a glance" view of when things changed in the access they are managing (without having to dive into often-complex audit logs).

Describe the solution you'd like Similar to the READ API in OpenFGA, storing and returning timestamps for relationship tuples would faciliate this greatly.

Adding the tuple and attribute modification timestamps to the read APIs could look like this:

{
  "tuples": [
    {
      "entity": {
        "type": "<string>",
        "id": "<string>"
      },
      "relation": "<string>",
      "subject": {
        "type": "<string>",
        "id": "<string>",
        "relation": "<string>"
      },
      "timestamp": "2021-10-06T15:32:11.128Z" # <-- New field here
    }
  ],
  "continuous_token": "<string>"
}
{
  "attributes": [
    {
      "entity": {
        "type": "<string>",
        "id": "<string>"
      },
      "attribute": "<string>",
      "value": {
        "@type": "<string>"
      },
      "timestamp": "2021-10-06T15:32:11.128Z" # <-- New field here
    }
  ],
  "continuous_token": "<string>"
}

It would also be extremely useful to be able to "spoof" the modification timestamps when writing tuples, to facilitate migration from other authorization systems, or otherwise be the authority on modification timestamps in your app (perhaps from a company-wide central time authority).

cr, err := client.Data.Write(context.Background(), &v1.DataWriteRequest{
    TenantId: "t1",
    Metadata: &v1.DataWriteRequestMetadata{
        SchemaVersion: "",
    },
    Tuples: []*v1.Tuple{
        {
            Entity: &v1.Entity{
                Type: "document",
                Id:   "1",
            },
            Relation: "editor",
            Subject:  &v1.Subject{
                Type: "user",
                Id:   "1",
                Relation: "",
            },
            Timestamp: time.Now(), // <-- New field here
        },
    },
    Attributes: []*v1.Attribute{
        {
            Entity: &v1.Entity{
                Type: "document",
                Id:   "1",
            },
            Attribute: "is_private",
            Value:     value,
            Timestamp: time.Now(), // <-- New field here
        },
    },
})

Describe alternatives you've considered It's possible to create "dummy entities" with attributes to store this data, but it adds significant complexity to the application code read pathways.

Additional context For example our groups management page here at CircleCI (where we are currently evaluating a swich from our in-house authorization engine to Permify):

Image

pete-woods avatar Mar 21 '25 09:03 pete-woods

@ucatbas hi - here's the feature request :-)

pete-woods avatar Mar 21 '25 09:03 pete-woods

Approved

Charlotte1959 avatar Jul 05 '25 03:07 Charlotte1959