Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
inherit_from: .rubocop_todo.yml
require:
plugins:
- rubocop-rails
Rails:
Enabled: False
Expand Down
2 changes: 1 addition & 1 deletion .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Metrics/MethodLength:
Enabled: false
Metrics/BlockLength:
Enabled: false
Metrics/LineLength:
Layout/LineLength:
Max: 121
Metrics/ParameterLists:
Enabled: false
Expand Down
53 changes: 52 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,49 @@ descope_client = Descope::Client.new(
)
```

### Auth Management Key

Authentication methods whose public access has been disabled can still be used by providing an
auth management key. When set, it is sent along with every authentication request.

Create one in the [Descope Console](https://app.descope.com/settings/company/managementkeys) with
either the `Authentication` or `Full Access` scope on the project or company.

```ruby
# Initialized after setting the DESCOPE_PROJECT_ID and DESCOPE_AUTH_MANAGEMENT_KEY env vars
descope_client = Descope::Client.new({})

# ** Or directly **
descope_client = Descope::Client.new(
{
project_id: '<project_id>',
auth_management_key: ENV['AUTH_MGMT_KEY']
}
)
```

**Note**: the auth management key can, and probably should, be a different management key than the
one provided for [management API usage](#setup-1). The auth management key is never sent on
management requests, and the management key is never sent on authentication requests.

### Request timeout

Every request is bounded by a 60 second timeout, matching the other Descope server SDKs. Raise it
for calls that legitimately take longer, such as `export_project` on a large project:

```ruby
descope_client = Descope::Client.new(
{
project_id: '<project_id>',
timeout_seconds: 180
}
)
```

### Important Logging note
You may pass `log_level: 'debug'` to the client config or use `DESCOPE_LOG_LEVEL` env var.
Be aware that only the management key is truncated, and the JWT responses are printed on debug
Be aware that everything after the project ID in the `Authorization` header is masked, but the JWT
responses are printed on debug

Do not run with log level debug on Production!

Expand Down Expand Up @@ -504,6 +544,8 @@ in nature. Please use responsibly.

To use the management API you'll need a `Management Key` along with your `Project ID`.
Create one in the [Descope Console](https://app.descope.com/settings/company/managementkeys).
This key is used only for management functions - to reach authentication methods whose public
access has been disabled, use the [Auth Management Key](#auth-management-key) instead.

```ruby
require 'descope'
Expand Down Expand Up @@ -1457,6 +1499,15 @@ You can find various usage examples in the [examples folder](https://github.com/
bundle install
```

### Environment variables

```bash
export DESCOPE_PROJECT_ID=<ProjectID>
export DESCOPE_MANAGEMENT_KEY=<ManagementKey>
# Optional, only needed for authentication methods with disabled public access
export DESCOPE_AUTH_MANAGEMENT_KEY=<AuthManagementKey>
```

### Run tests

Running all tests:
Expand Down
2 changes: 1 addition & 1 deletion lib/descope/api/v1/auth/enchantedlink.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def enchanted_link_sign_in(login_id: nil, uri: nil, login_options: nil, refresh_
validate_refresh_token_provided(login_options, refresh_token)
body = enchanted_link_compose_signin_body(login_id, uri, login_options)
uri = enchanted_link_compose_signin_url
post(uri, body, nil, refresh_token)
post(uri, body, {}, refresh_token)
end

def enchanted_link_sign_up(login_id: nil, uri: nil, user: {})
Expand Down
15 changes: 8 additions & 7 deletions lib/descope/api/v1/management/access_key.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ def create_access_key(name: nil, expire_time: nil, role_names: nil, key_tenants:
role_names ||= []
key_tenants ||= []
validate_tenants(key_tenants)
post(ACCESS_KEY_CREATE_PATH, access_key_compose_create_body(name, expire_time, role_names, key_tenants, custom_claims))
mgmt_post(ACCESS_KEY_CREATE_PATH,
access_key_compose_create_body(name, expire_time, role_names, key_tenants, custom_claims))
end

def access_key_compose_create_body(name, expire_time, role_names, key_tenants, custom_claims)
Expand All @@ -34,7 +35,7 @@ def load_access_key(id)
# @param id [string] The access key id.
# @see https://docs.descope.com/api/openapi/accesskeymanagement/operation/LoadAccessKey/

get(ACCESS_KEY_LOAD_PATH, { id: })
mgmt_get(ACCESS_KEY_LOAD_PATH, { id: })
end

def search_all_access_keys(tenant_ids = nil)
Expand All @@ -43,7 +44,7 @@ def search_all_access_keys(tenant_ids = nil)
request_params = {
tenantIds: tenant_ids
}
post(ACCESS_KEYS_SEARCH_PATH, request_params)
mgmt_post(ACCESS_KEYS_SEARCH_PATH, request_params)
end

def update_access_key(id: nil, name: nil)
Expand All @@ -53,27 +54,27 @@ def update_access_key(id: nil, name: nil)
id:,
name:
}
post(ACCESS_KEY_UPDATE_PATH, request_params)
mgmt_post(ACCESS_KEY_UPDATE_PATH, request_params)
end

def deactivate_access_key(id)
# Deactivate an existing access key. IMPORTANT: This deactivated key will not be usable from this stage.
# It will, however, persist, and can be activated again if needed.
# @see https://docs.descope.com/api/openapi/accesskeymanagement/operation/DeactivateAccessKey/
post(ACCESS_KEY_DEACTIVATE_PATH, { id: })
mgmt_post(ACCESS_KEY_DEACTIVATE_PATH, { id: })
end

def activate_access_key(id)
# Activate an existing access key. IMPORTANT: Only deactivated keys can be activated again,
# and become usable once more. New access keys are active by default.
# @see https://docs.descope.com/api/openapi/accesskeymanagement/operation/ActivateAccessKey/
post(ACCESS_KEY_ACTIVATE_PATH, { id: })
mgmt_post(ACCESS_KEY_ACTIVATE_PATH, { id: })
end

def delete_access_key(id)
# Delete an existing access key. IMPORTANT: This action is irreversible. Use carefully.
# @see https://docs.descope.com/api/openapi/accesskeymanagement/operation/DeleteAccessKey/
post(ACCESS_KEY_DELETE_PATH, { id: })
mgmt_post(ACCESS_KEY_DELETE_PATH, { id: })
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/descope/api/v1/management/analytics.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def analytics_search(
request_params[:geos] = geos unless geos.nil?
request_params[:tenants] = tenants unless tenants.nil?

post(ANALYTICS_SEARCH_PATH, request_params)
mgmt_post(ANALYTICS_SEARCH_PATH, request_params)
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/descope/api/v1/management/audit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def audit_search(
request_params[:text] = text unless text.nil?
request_params[:from] = from_ts.to_i * 1000 unless from_ts.nil?
request_params[:to] = to_ts.to_i * 1000 unless to_ts.nil?
res = post(AUDIT_SEARCH, request_params)
res = mgmt_post(AUDIT_SEARCH, request_params)
raise Descope::AuthException, "could not get audits: #{res}" if res['audits'].nil?

{ 'audits' => res['audits'].map { |audit| convert_audit_record(audit) } }
Expand All @@ -79,7 +79,7 @@ def audit_create_event(action: nil, type: nil, data: nil, user_id: nil, actor_id
}
request_params[:userId] = user_id unless user_id.nil?

post(AUDIT_CREATE_EVENT, request_params)
mgmt_post(AUDIT_CREATE_EVENT, request_params)
end

private
Expand Down
30 changes: 15 additions & 15 deletions lib/descope/api/v1/management/authz.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,17 @@ def authz_save_schema(schema: nil, upgrade: false)
# Schema name can be used for projects to track versioning.
# @see https://docs.descope.com/api/openapi/authz/operation/SaveSchema/
request_params = { schema:, upgrade: }
post(AUTHZ_SCHEMA_SAVE, request_params)
mgmt_post(AUTHZ_SCHEMA_SAVE, request_params)
end

def authz_delete_schema
# Delete the schema for the project which will also delete all relations.
post(AUTHZ_SCHEMA_DELETE)
mgmt_post(AUTHZ_SCHEMA_DELETE)
end

def authz_load_schema
# Load the schema for the project.
post(AUTHZ_SCHEMA_LOAD)
mgmt_post(AUTHZ_SCHEMA_LOAD)
end

def authz_save_namespace(namespace: nil, old_name: nil, schema_name: nil)
Expand All @@ -59,14 +59,14 @@ def authz_save_namespace(namespace: nil, old_name: nil, schema_name: nil)
request_params = { namespace: namespace }
request_params[:oldName] = old_name unless old_name.nil?
request_params[:schemaName] = schema_name unless schema_name.nil?
post(AUTHZ_NS_SAVE, request_params)
mgmt_post(AUTHZ_NS_SAVE, request_params)
end

def authz_delete_namespace(name: nil, schema_name: nil)
# Delete the given namespace
request_params = { name: name }
request_params[:schemaName] = schema_name unless schema_name.nil?
post(AUTHZ_NS_DELETE, request_params)
mgmt_post(AUTHZ_NS_DELETE, request_params)
end

def authz_save_relation_definition(relation_definition: nil, namespace: nil, old_name: nil, schema_name: nil)
Expand All @@ -78,14 +78,14 @@ def authz_save_relation_definition(relation_definition: nil, namespace: nil, old
}
request_params[:old_name] = old_name unless old_name.nil?
request_params[:schemaName] = schema_name unless schema_name.nil?
post(AUTHZ_RD_SAVE, request_params)
mgmt_post(AUTHZ_RD_SAVE, request_params)
end

def authz_delete_relation_definition(name: nil, namespace: nil, schema_name: nil)
# Delete the given relation definition
request_params = { name: , namespace: }
request_params[:schemaName] = schema_name unless schema_name.nil?
post(AUTHZ_RD_DELETE, request_params)
mgmt_post(AUTHZ_RD_DELETE, request_params)
end

def authz_create_relations(relations = nil)
Expand Down Expand Up @@ -114,22 +114,22 @@ def authz_create_relations(relations = nil)
# }
# Each relation should have exactly one of: target, targetSet, query
# Regarding query above, it should be specified if the target is a set of users that matches the query - all fields are optional
post(AUTHZ_RE_CREATE, { relations: })
mgmt_post(AUTHZ_RE_CREATE, { relations: })
end

def authz_delete_relations(relations = nil)
# Delete the given relations based on the existing schema
post(AUTHZ_RE_DELETE, { relations: })
mgmt_post(AUTHZ_RE_DELETE, { relations: })
end

def authz_delete_relations_for_resources(resources = nil)
# Delete all relations for the given resources
post(AUTHZ_RE_DELETE_RESOURCES, { resources: })
mgmt_post(AUTHZ_RE_DELETE_RESOURCES, { resources: })
end

def authz_has_relations?(relation_queries = nil)
# Queries the given relations to see if they exist returning true if they do
post(AUTHZ_RE_HAS_RELATIONS, { relationQueries: relation_queries })
mgmt_post(AUTHZ_RE_HAS_RELATIONS, { relationQueries: relation_queries })
end

def authz_who_can_access?(resource: nil, relation_definition: nil, namespace: nil)
Expand All @@ -139,21 +139,21 @@ def authz_who_can_access?(resource: nil, relation_definition: nil, namespace: ni
relationDefinition: relation_definition,
namespace:
}
post(AUTHZ_RE_WHO, request_params)
mgmt_post(AUTHZ_RE_WHO, request_params)
end

def authz_resource_relations(resources: nil)
post(AUTHZ_RE_RESOURCE, { resources: })
mgmt_post(AUTHZ_RE_RESOURCE, { resources: })
end

def authz_target_relations(targets: nil)
# Returns the list of all defined relations (not recursive) for the given targets.
post(AUTHZ_RE_TARGETS, { targets: })
mgmt_post(AUTHZ_RE_TARGETS, { targets: })
end

def authz_what_can_target_access?(target: nil)
# Returns the list of all relations for the given target including derived relations from the schema tree.
res = post(AUTHZ_RE_TARGET_ALL, { target: })
res = mgmt_post(AUTHZ_RE_TARGET_ALL, { target: })
raise Descope::AuthException, "could not get relation for target: #{res}" if res['relations'].nil?

res['relations']
Expand Down
10 changes: 5 additions & 5 deletions lib/descope/api/v1/management/descoper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module Descoper
def create_descoper(descopers = nil)
# Create the given descopers.
# descopers (Array): the descopers to create.
put(DESCOPER_CREATE_PATH, { descopers: descopers })
mgmt_put(DESCOPER_CREATE_PATH, { descopers: descopers })
end

def update_descoper(id: nil, attributes: nil, rbac: nil)
Expand All @@ -21,22 +21,22 @@ def update_descoper(id: nil, attributes: nil, rbac: nil)
attributes: attributes,
rbac: rbac
}
patch(DESCOPER_UPDATE_PATH, request_params)
mgmt_patch(DESCOPER_UPDATE_PATH, request_params)
end

def get_descoper(id: nil)
# Get a descoper by id.
get(DESCOPER_GET_PATH, { id: id })
mgmt_get(DESCOPER_GET_PATH, { id: id })
end

def delete_descoper(id: nil)
# Delete a descoper by id.
delete(DESCOPER_DELETE_PATH, { id: id })
mgmt_delete(DESCOPER_DELETE_PATH, { id: id })
end

def search_descopers
# Search (list) all descopers.
post(DESCOPER_SEARCH_PATH, {})
mgmt_post(DESCOPER_SEARCH_PATH, {})
end
end
end
Expand Down
12 changes: 6 additions & 6 deletions lib/descope/api/v1/management/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,32 @@ module Engine

def create_engine(name:)
# Create a new engine with the given name.
post(ENGINE_CREATE_PATH, { name: })
mgmt_post(ENGINE_CREATE_PATH, { name: })
end

def update_engine(id:, name:)
# Update an existing engine with the given id and name.
post(ENGINE_UPDATE_PATH, { id:, name: })
mgmt_post(ENGINE_UPDATE_PATH, { id:, name: })
end

def delete_engine(id:)
# Delete an existing engine. IMPORTANT: This action is irreversible. Use carefully.
post(ENGINE_DELETE_PATH, { id: })
mgmt_post(ENGINE_DELETE_PATH, { id: })
end

def load_engine(id:)
# Load engine by id.
get(ENGINE_LOAD_PATH, { id: })
mgmt_get(ENGINE_LOAD_PATH, { id: })
end

def load_all_engines
# Load all engines.
get(ENGINE_LOAD_ALL_PATH)
mgmt_get(ENGINE_LOAD_ALL_PATH)
end

def rotate_engine_secret(id:)
# Rotate the secret for the given engine.
post(ENGINE_ROTATE_SECRET_PATH, { id: })
mgmt_post(ENGINE_ROTATE_SECRET_PATH, { id: })
end
end
end
Expand Down
Loading