Skip to content

feature: support contextual tuples and context params #43

@jimmyjames

Description

@jimmyjames

When making an FGA check, contextual tuples and/or a context parameter can be passed for more advanced authorization scenarios.

Contextual tuples

Contextual tuples can be sent in a check request and will be part of the authorization evaluation as if they exist they in the store.

For example, user:123 is a member of the marketing group, and the marketing group has been granted the viewer relationship for document:roadmap.

We can send conditional tuples on the request to inform the groups to which user:123 belongs (e.g., from a groups claim):

var body = new ClientCheckRequest()
      .user("user:123")
      .relation("viewer")
      ._object("document:1")
      .contextualTuples(
          List.of(
              new ClientTupleKey()
                  .user("user:123")
                  .relation("member")
                  ._object("group:marketing"),
              new ClientTupleKey()
                  .user("user:123")
                  .relation("member")
                  ._object("group:everyone")
          ));

var allowed = fga.check(body).get().getAllowed();

Conext with conditions

An authorization model may define a condition, and a context parameter can be supplied to the check request as part of the authorization criteria. For example, a condition could exist that specifies that user:anne has viewer relationship to document:roadmap only if the current time is within 10 minutes of the time access was granted.

Example model:

model
  schema 1.1

type user

type document
  relations
    define viewer: [user with non_expired_grant]

condition non_expired_grant(current_time: timestamp, grant_time: timestamp, grant_duration: duration) {
  current_time < grant_time + grant_duration
}

Write a tuple with a condition:

var body = new ClientWriteRequest()
        .writes(List.of(
                new ClientTupleKey()
                        .user("user:123")
                        .relation("viewer")
                        ._object("document:roadmap")
                        .condition(new ClientRelationshipCondition()
                                .name("non_expired_grant")
                                .context(Map.of("grant_time", "2023-01-01T00:00:00Z","grant_duration", "10m"))
                        )
                        
        ));

var response = fgaClient.write(body, options).get();

Send a check request including the context parameter:

var body = new ClientCheckRequest()
      .user("user:123")
      .relation("viewer")
      ._object("document:1")
      .context(Map.of("current_time", "2023-01-01T00:10:01Z"));

var response = fga.check(body).get();

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions