docs icon indicating copy to clipboard operation
docs copied to clipboard

SDK: assigning a role to a policy when creating or updating it, always fails

Open fedeandri opened this issue 10 months ago • 7 comments

Describe the Bug

I'm creating a series of scripts to set up multi-tenancy programmatically.

I'm using the SDK v19.1.0.

ISSUE Assigning a role when creating/updating a policy always makes the call fail despite the policy object having a roles property (so I'm assuming it's doable) https://docs.directus.io/reference/system/policies.html

Similarly, assigning a policy to a role makes it fail despite the role object having a policies property https://docs.directus.io/reference/system/roles.html

So it seems like the problem is related to creating the necessary relationship in the directus_access table.

Functions I tested that present the same problem:

  • createPolicy
  • createPolicies
  • updatePolicy
  • updateRole

To Reproduce

Test script to replicate the issue when creating a policy assigned to a specific role:

require('dotenv').config();

const DIRECTUS_URL = process.env.DIRECTUS_URL;
const DIRECTUS_ADMIN_EMAIL = process.env.DIRECTUS_ADMIN_EMAIL;
const DIRECTUS_ADMIN_PASSWORD = process.env.DIRECTUS_ADMIN_PASSWORD;

const userRole = {
    id: 'replace-with-existing-role-id',
    name: 'User'
};

const { 
    createDirectus, 
    rest, 
    login, 
    staticToken,
    createPolicy,
} = require('@directus/sdk'); // "@directus/sdk": "^19.1.0"
  

async function setupPolicies() {
    try {
        console.log('Starting policies setup...');

        // Get the token using a temporary client
        console.log('Authenticating with Directus...');
        const tempClient = createDirectus(DIRECTUS_URL)
            .with(rest());

        let loginResult;

        try {
            loginResult = await tempClient.request(
            login(DIRECTUS_ADMIN_EMAIL, DIRECTUS_ADMIN_PASSWORD)
            );
            console.log('Successfully authenticated with Directus');
        } catch (error) {
            console.error('Failed to authenticate with Directus:', error);
            throw error;
        }

        // Create a new client with the static token
        const directus = createDirectus(DIRECTUS_URL)
            .with(staticToken(loginResult.access_token))
            .with(rest());

        console.log('Setting up policy for User role...');

        try {
            const policyName = 'Read Own User Profile';
            const policyDescription = 'Allows users to read their own user profile';
            
            console.log(`Creating new policy "${policyName}" for role ${userRole.name} (${userRole.id})`);
            const policy = await directus.request(createPolicy({
                name: policyName,
                description: policyDescription,
                admin_access: false,
                app_access: false,
                roles: [userRole.id],
            }));

            console.log(`Successfully created policy with ID: ${policy.id}`);


        } catch (error) {
            console.error('Failed to set up User role policies:', error);
            throw error;
        }

    } catch (error) {
        console.error('Fatal error during policies setup:', error);
        throw error;
    }
}

// Run the setup
setupPolicies()
  .then(() => console.log('Setup completed successfully'))
  .catch(error => {
    console.error('Setup failed:', error);
    process.exit(1);
  });

Directus Version

v11.6.1

Hosting Strategy

Self-Hosted (Docker Image)

Database

PostgreSQL 17.4

fedeandri avatar Apr 14 '25 10:04 fedeandri