permission_callback was optional until recently and defaulting it to __return_true is the same as having no authorisation at all, which is how endpoints intended for the admin end up public.
register_rest_route( 'turkerdev/v1', '/reports/(?P<id>d+)', array(
'methods' => WP_REST_Server::READABLE,
'callback' => 'turkerdev_get_report',
'permission_callback' => function ( WP_REST_Request $request ) {
return current_user_can( 'read_report', (int) $request['id'] );
},
'args' => array(
'id' => array(
'validate_callback' => 'is_numeric',
'sanitize_callback' => 'absint',
),
),
) );
Checking a capability against the specific object rather than a blanket manage_options is what makes the endpoint usable by a non-administrator without opening it to everything. The args block is the other half and is frequently omitted: validation there runs before the callback, so the callback can assume its input is well formed. Returning a WP_Error from the permission callback rather than false lets you say why, which matters for debugging a client.