Documentation

Syncing Auth to FGA

← All docs

Syncing Auth to FGA

Sync AuthServer users and memberships into FGA subjects and grants.

When using both AuthServer and FGA, you need to sync authenticated users into the FGA model so they can be authorized. The typical pattern is to sync on login.

The pattern

After login, ensure the user exists as an FGA subject, the organization exists as an FGA resource, and the membership is mapped to a grant:

public async Task EnsureUserAccessAsync(
    string userId, string organizationId, CancellationToken ct)
{
    var user = await _context.Set<SqlOSUser>()
        .FirstAsync(x => x.Id == userId, ct);
    var organization = await _context.Set<SqlOSOrganization>()
        .FirstAsync(x => x.Id == organizationId, ct);
    var membership = await _context.Set<SqlOSMembership>()
        .FirstAsync(x => x.UserId == userId
            && x.OrganizationId == organizationId
            && x.IsActive, ct);

    await EnsureSubjectAsync(user, organizationId, ct);
    await EnsureOrganizationResourceAsync(organization, ct);
    await EnsureMembershipGrantAsync(userId, organizationId, membership.Role, ct);
}

What each step does

EnsureSubjectAsync -- creates or updates SqlOSFgaSubject and SqlOSFgaUser for the authenticated user.

EnsureOrganizationResourceAsync -- creates an SqlOSFgaResource for the organization under root (if it doesn't exist).

EnsureMembershipGrantAsync -- creates a grant linking the user to a role on the organization resource, mapping the auth membership role to an FGA role:

Auth roleFGA role
admin or ownerorg_admin (full access)
everything elseorg_member (read access)

When to call

Call EnsureUserAccessAsync after successful login, during token creation:

if (!string.IsNullOrWhiteSpace(tokens.OrganizationId))
{
    await fgaService.EnsureUserAccessAsync(
        user.Id, tokens.OrganizationId, ct);
}

The example app calls this in the token response helper, so every login automatically ensures the user has the right FGA grants based on their auth membership.

Why sync instead of query auth directly?

FGA subjects and grants are stored in tables optimized for the authorization query (tree walk + table-valued function). By syncing auth data into FGA at login time, authorization checks run entirely in SQL without joining against auth tables at query time.