Skip to main content

Check permissions with the Ruby SDK

Connect a Ruby application to Permit.io and call permit.check() to allow or deny a request. This quickstart is for backend developers who have a Permit.io policy and want to enforce the policy from Ruby code. At the end, a Ruby app returns an allow or deny result for each request, and the check appears in the Permit audit log.

What the Ruby SDK covers

The permit-sdk gem implements permit.check(), permit.sync_user(), read calls for users, tenants, and resources, and Permit Elements login. Policy management calls, such as creating roles or resources, are not in the gem: use the Permit API or another SDK for those. See SDK feature parity.

Prerequisites

  • A Permit.io account with at least one policy. If you don't have a policy yet, complete the Quickstart.
  • Docker, if you run the policy decision point (PDP) as a container. See Install Docker.

1. Get your environment API key

The SDK and the PDP authenticate with Permit using an environment API key. Each API key belongs to one environment.

  1. In the Permit dashboard, open the Projects screen.
  2. Find the project and the environment you want to connect to.
  3. On the environment card, click the Three dots menu icon icon in the top-right corner.
  4. Click Copy API Key.
Projects screen with the environment card menu open and Copy API Key highlighted
Copy the API key from the user menu

You can also copy the API key of the active environment from User Menu > Copy Environment Key.

User menu open with Copy Environment Key highlighted
The user menu copies the active environment's key

The API key you copy from the user menu belongs to the active environment in the sidebar. If you switch the active environment and click Copy Environment Key again, you copy a different API key: the key of the newly active environment.

Keep the API key out of source control

Anyone with your environment API key can change that environment's policy and data through the Permit API. Load the API key from an environment variable or a secret store, and don't commit the API key to your repository.

2. Set up your policy decision point (PDP)

Your application sends each permission check to a policy decision point (PDP), the service that evaluates the check against your policy. Use the managed Cloud PDP that Permit.io runs, or run the PDP as a Docker container on your machine.

The SDK examples on this page connect to a container PDP at http://localhost:7766. To use the Cloud PDP, set the SDK's PDP URL to https://cloudpdp.api.permit.io instead.

The Cloud PDP needs no installation. Pass the Cloud PDP URL when you initialize the Permit SDK. The following Node.js example shows the shape. The SDK install step further down shows the same setting in this page's language. Replace [YOUR_API_KEY] with your environment API key:

// This line initializes the SDK and connects your app
// to the Permit.io Cloud PDP.

const permit = new Permit({
pdp: "https://cloudpdp.api.permit.io",
// your API Key
token: "[YOUR_API_KEY]",
});
Cloud PDP policy models

The Cloud PDP is a managed service that Permit.io runs. The Cloud PDP supports RBAC (role-based access control) and ReBAC (relationship-based access control) policies. The Cloud PDP does not support ABAC (attribute-based access control) policies, so the ABAC examples on this page need a container PDP.

For capabilities, limits, and when to choose each PDP type, see Cloud PDP capabilities.

3. Install the Ruby SDK and check permissions

Install and initialize the Ruby SDK

Install the permit-sdk gem, load the SDK, and create a Permit client that connects to your PDP.

  1. Install the Permit.io Ruby SDK:

    gem install permit-sdk
  2. Load the SDK in your code:

    require 'permit'
  3. Create a Permit client with Permit.new(token, pdp_url). Replace <YOUR_API_KEY> with your environment API key. The second argument is the PDP URL, and defaults to http://localhost:7766, the address of a container PDP on your machine:

    require 'permit'
    permit = Permit.new("<YOUR_API_KEY>", "http://localhost:7766") # the PDP url is optional

To send checks to the managed Cloud PDP instead of a container PDP, pass the Cloud PDP URL:

require 'permit'
permit = Permit.new("<YOUR_API_KEY>", "https://cloudpdp.api.permit.io")

The Cloud PDP supports RBAC (role-based access control) and ReBAC (relationship-based access control) policies. ABAC (attribute-based access control) checks need a container PDP. See Cloud PDP capabilities.

Check permissions with the Ruby SDK

Call permit.check() with three arguments. permit.check() returns true when the policy allows the action, and false otherwise.

ArgumentDescription
userThe user key as a string, or a hash with key and optional first_name, last_name, email, and attributes. The user key is typically the user ID from your authentication provider.
actionThe action key as a string, for example "create".
resourceThe resource type key as a string, for example "document", or a hash with type, tenant, and attributes. A string resource uses the default tenant.

The following examples check whether the user john@permit.io can create a document. This example passes the user and the resource as strings:

require 'permit'
permit = Permit.new("<YOUR_API_KEY>", "http://localhost:7766") # the PDP url is optional

permitted = permit.check("john@permit.io", "create" , "document")
if permitted
puts "john@permit.io is permitted to create a document"
else
puts "john@permit.io is not permitted to create a document"
end

This example passes the user and the resource as hashes:

require 'permit'
permit = Permit.new("<YOUR_API_KEY>", "http://localhost:7766") # the PDP url is optional

user_hash = {"key": "john@permit.io", "first_name": "john", "last_name": "doe", "email": "john@permit.io"}
resource_hash = {"type": "document", "tenant": "default"}
permitted = permit.check(user_hash, "create" , resource_hash)
if permitted
puts "john@permit.io is permitted to create a document"
else
puts "john@permit.io is not permitted to create a document"
end

If john@permit.io exists in your environment and has a role that grants create on document, both examples print john@permit.io is permitted to create a document. Otherwise, the examples print john@permit.io is not permitted to create a document. To add users and assign roles, see Sync users.

A PDP error raises an exception instead of returning false

When the PDP answers with a status code other than 200, for example because the PDP URL is wrong or the API key belongs to another environment, permit.check() raises a RuntimeError that names the status code. Handle the exception in request code, or the request fails with a server error instead of a deny.

Check a permission in a specific tenant

In a multi-tenant application, pass the tenant key in the tenant field of the resource hash, as resource_hash does in the hash example. To look up the keys of your tenants, call the list tenants API. In this example, replace user, action, resource, and tenant with a user key, action key, resource key, and tenant key from your environment:

if permit.check("user", "action", { "type": "resource", "tenant": "tenant" })
# the policy allows the action in that tenant
end
Where checks run and where user data is stored

permit.check() sends each check to the PDP URL you configure. A container PDP evaluates checks on your machine, using policy and data that the PDP loads from Permit. Users, roles, and attributes that you create in the dashboard or sync through the Permit API are stored in the Permit control plane.

Run a full Ruby example app

This single-file WEBrick app listens on port 4000 and runs a permission check on each request. The app uses the default PDP URL, http://localhost:7766. The app loads the json library, because the response bodies call to_json on a hash.

  1. Install the permit-sdk and webrick gems:

    gem install permit-sdk webrick
  2. Save the following code as app.rb. Replace <YOUR_API_KEY> with your environment API key, and john@permit.io with the key of a user in your environment:

    require 'json'
    require 'webrick'
    require 'permit'

    permit = Permit.new("<YOUR_API_KEY>")

    server = WEBrick::HTTPServer.new(Port: 4000)

    server.mount_proc '/' do |_, res|
    res['Content-Type'] = 'application/json'

    permitted = permit.check("john@permit.io", "read", "document")
    if permitted
    res.status = 200
    res.body = { result: "john@permit.io is PERMITTED to read document!" }.to_json
    next
    end
    res.status = 403
    res.body = { result: "john@permit.io is NOT PERMITTED to read document" }.to_json
    end

    trap 'INT' do server.shutdown end

    server.start
  3. Run the app:

    ruby app.rb
  4. Open http://localhost:4000 in a browser.

If the user's role grants read on document, the page returns HTTP 200 with this body:

{"result":"john@permit.io is PERMITTED to read document!"}

Otherwise, the page returns HTTP 403 with john@permit.io is NOT PERMITTED to read document. If the page returns is NOT PERMITTED and you expect an allow, check that the user has a role that grants read on document, and that the container PDP runs with an API key from the same environment.

Check ABAC permissions with the Ruby SDK

An attribute-based access control (ABAC) policy grants permissions based on user and resource attributes, grouped into user sets and resource sets. See ABAC policy components. ABAC checks need a container PDP.

To check an ABAC policy, pass a resource hash with an attributes hash. In this example, user is a user key or user hash, and close and resource stand for an action key and a resource key from your environment:

if permit.check(user, 'close', { "type": "resource", "attributes": {"hasApproval": "true"}, "tenant": "default" })
# the policy allows the action on a resource that has the attribute values
end

For more check options, see Check permissions with permit.check().

4. Confirm the check in the audit log

Open the Audit Log screen in the Permit dashboard. Each permission check from your application appears as an entry with the user, the action, the resource, and the decision.

If the check doesn't appear in the audit log, see Troubleshoot audit logs.

Next steps