Class: Conjur::API
- Inherits:
-
Object
- Object
- Conjur::API
- Defined in:
- lib/conjur/base.rb,
lib/conjur/api/info.rb,
lib/conjur/core-api.rb,
lib/conjur/api/audit.rb,
lib/conjur/api/authn.rb,
lib/conjur/api/hosts.rb,
lib/conjur/api/roles.rb,
lib/conjur/api/users.rb,
lib/conjur/layer-api.rb,
lib/conjur/api/groups.rb,
lib/conjur/api/layers.rb,
lib/conjur-api/version.rb,
lib/conjur/api/pubkeys.rb,
lib/conjur/api/secrets.rb,
lib/conjur/pubkeys-api.rb,
lib/conjur/api/deputies.rb,
lib/conjur/api/ldapsync.rb,
lib/conjur/api/resources.rb,
lib/conjur/api/variables.rb,
lib/conjur/host-factory-api.rb,
lib/conjur/api/host_factories.rb
Overview
This class provides access to the Conjur services.
Direct Known Subclasses
Conjur::Audit::API, Conjur::Authn::API, Conjur::Authz::API, Core::API
Defined Under Namespace
Modules: MonotonicTime, TokenExpiration Classes: APIKeyAuthenticator, TokenFileAuthenticator, UnableAuthenticator
Authorization: Resources collapse
- GLOBAL_PRIVILEGE_RESOURCE =
The resource which grants global privileges to Conjur. Privileges given on this resource apply to any record in the system. There are two defined global privileges:
- elevate permission is granted for any action.
- reveal methods which list records will always return every matching record, regardless of whether the user has any privileges on these records or not. Services can also choose to attach additional semantics to reveal, such as allowing the user to show non-sensitive attributes of any record.
Global privileges are available in Conjur 4.5 and later.
"!:!:conjur"
Constant Summary collapse
- VERSION =
"4.30.0"
Instance Attribute Summary collapse
-
#api_key ⇒ String
readonly
The api key used to create this instance.
-
#audit_resources ⇒ Object
An array of resource ids that should be included in any audit records generated by requsts made by this instance of the api.
-
#audit_roles ⇒ Object
An array of role ids that should be included in any audit records generated by requsts made by this instance of the api.
-
#authenticator ⇒ Object
readonly
Returns the value of attribute authenticator.
-
#privilege ⇒ Object
The optional global privilege (e.g. 'elevate' or 'reveal') which should be attempted on the request.
-
#remote_ip ⇒ Object
readonly
An optional IP address to be recorded in the audit record for any actions performed by this API instance.
Audit Service collapse
-
#audit(options = {}, &block) ⇒ Array<Hash>
Return up to 100 audit events visible to the current authorized role.
-
#audit_resource(resource, options = {}, &block) ⇒ Array<Hash>
Return up to 100 audit events visible to the current role and related to the given resource.
-
#audit_role(role, options = {}, &block) ⇒ Array<Hash>
Return up to 100 audit events visible to the current role and related to the given role.
-
#audit_send(input) ⇒ Object
Send custom audit event.
Authentication Methods collapse
-
.authenticate(username, password) ⇒ String
The Conjur authenticate operation exchanges Conjur credentials for a token.
-
.login(username, password) ⇒ String
The Conjur login operation exchanges a username and a password for an api key.
-
.login_cas(username, password, cas_api_url) ⇒ String
This method logs in via CAS.
-
.update_password(username, password, new_password)
Change a user's password.
Password and API key management collapse
-
.rotate_api_key(username, password) ⇒ String
Rotate the currently authenticated user's API key by generating and returning a new one.
Directory: Hosts collapse
-
#create_host(options = nil) ⇒ Conjur::Host
Create a new
host
asset. -
#host(id) ⇒ Conjur::Host
Get a host by its unqualified id.
Authorization: Roles collapse
-
#create_role(role, options = {}) ⇒ Conjur::Role
Create a Role with the given id.
-
#current_role ⇒ Conjur::Role
Return a Role object representing the role (typically a user or host) that this api is authenticated as.
-
#role(role) ⇒ Conjur::Role
Return a Role representing a role with the given id.
-
#role_graph(roles, options = {}) ⇒ Conjur::Graph
Fetch a Graph representing the relationships of a given role or roles.
Directory: Users collapse
-
#create_user(login, options = {}) ⇒ Conjur::User
Create a Conjur User.
-
#user(login) ⇒ Conjur::User
Return an object representing a user with the given login.
Directory: Groups collapse
-
#create_group(id, options = {}) ⇒ Conjur::Group
Create a new group with the given identifier.
-
#find_groups(options) ⇒ Array<String>
Find groups by GID.
-
#group(id) ⇒ Conjur::Group
Fetch a group with the given id.
-
#groups(options = {}) ⇒ Array<Conjur::Group>
List all Conjur groups visible to the current role.
Directory: Layers collapse
-
#create_layer(id, options = {}) ⇒ Conjur::Layer
Create a new layer with the given id.
-
#layer(id) ⇒ Conjur::Layer
Get a layer by its unqualified id.
-
#layers(options = {}) ⇒ Array<Conjur::Layer>
Get all layers visible to the current role.
Public Keys Service collapse
-
#add_public_key(username, key) ⇒ Object
Add an SSH public key for
username
. -
#delete_public_key(username, keyname)
Delete a specific public key for a user.
-
#public_key(username, keyname) ⇒ String
Fetch a specific key by name.
-
#public_key_names(username) ⇒ Array<String>
List the public key names for the given user.
-
#public_keys(username) ⇒ String
Fetch all public keys for the user.
Directory: Deputies collapse
-
#create_deputy(options = {}) ⇒ Conjur::Deputy
Create a Conjur deputy.
-
#deputy(id) ⇒ Conjur::Deputy
Find a Conjur deputy by id.
LDAP Sync Service collapse
-
#ldap_sync_policy(profile, options = {}) ⇒ Object
Fetch a Conjur policy that will bring Conjur into sync with the LDAP server specified by a profile.
- #ldap_sync_show_profile(profile, options = {}) ⇒ Object
Authorization: Resources collapse
-
#create_resource(identifier, options = {}) ⇒ Conjur::Role
Create a Conjur Resource.
-
#global_privilege_permitted?(privilege) ⇒ Boolean
Checks whether the client has a particular global privilege.
-
#resource(identifier) ⇒ Conjur::Resource
Find a resource by it's id.
-
#resources(opts = {}) ⇒ Array<Conjur::Resource>
Find all resources visible to the current role that match the given search criteria.
-
#resources_permitted?(kind, identifiers, privilege) ⇒ Array
First element is a Boolean, true if all checks passed, false otherwise.
Directory: Variables collapse
-
#create_variable(mime_type, kind, options = {}) ⇒ Conjur::Variable
Create a Conjur Variable.
-
#variable(id) ⇒ Conjur::Variable
Retrieve an object representing a Conjur Variable.
-
#variable_expirations(interval = nil) ⇒ Object
param interval a String containing an ISO8601 duration , or a number of seconds return [Hash] variable expirations that occur within the interval.
-
#variable_values(varlist) ⇒ Hash
Fetch the values of a list of variables.
Class Method Summary collapse
-
.appliance_health(remote_host = nil) ⇒ Hash
Return a Hash containing health information for this appliance, or for another host.
-
.appliance_info ⇒ Hash
Return a Hash containing various information about the Conjur appliance.
- .decode_audit_ids(ids) ⇒ Object
- .encode_audit_ids(ids) ⇒ Object
- .host_factory_asset_host ⇒ Object
-
.host_factory_create_host(token, id, options = {}) ⇒ Object
Creates a host and returns the response Hash.
-
.new_from_key(username, api_key, remote_ip = nil) ⇒ Conjur::API
Create a new API instance from a username and a password or api key.
-
.new_from_token(token, remote_ip = nil) ⇒ Conjur::API
Create a new API instance from a token issued by the Conjur authentication service.
-
.new_from_token_file(token_file, remote_ip = nil) ⇒ Conjur::API
Create a new API instance from a file containing a token issued by the Conjur authentication service.
-
.service_names ⇒ Array<String>
Return an Array of valid service names for your appliance.
-
.service_version(service) ⇒ Semantic::Version
Return the version of the given service presently running on the Conjur appliance.
Instance Method Summary collapse
-
#bootstrap(listener) ⇒ Object
Perform all commands in Conjur::Bootstrap::Command.
-
#create_host_factory(id, options = {}) ⇒ Object
Options: +layers+ list of host factory layers +roleid+ host factory role id +role+ host factory role.
-
#credentials ⇒ Hash
Credentials that can be merged with options to be passed to
RestClient::Resource
HTTP request methods. - #host_factory(id) ⇒ Object
-
#host_factory_create_host(token, id, options = {}) ⇒ Object
Creates a Host and returns a Host object.
- #init_from_key(username, api_key, remote_ip = nil) ⇒ Object
- #init_from_token(token, remote_ip = nil) ⇒ Object
- #init_from_token_file(token_file, remote_ip = nil) ⇒ Object
- #revoke_host_factory_token(token) ⇒ Object
- #show_host_factory_token(token) ⇒ Object
-
#token ⇒ Hash
The token used to authenticate requests made with the api.
-
#username ⇒ String
The name of the user as which this api instance is authenticated.
- #with_audit_resources(resource_ids) ⇒ Object
- #with_audit_roles(role_ids) ⇒ Object
-
#with_privilege(privilege) ⇒ Object
Return a new API object with the specified X-Conjur-Privilege.
Methods included from LogSource
Methods included from Escape
#fully_escape, #path_escape, #query_escape
Instance Attribute Details
#api_key ⇒ String (readonly)
The api key used to create this instance. This is only present when you created the api with new_from_key.#
170 171 172 |
# File 'lib/conjur/base.rb', line 170 def api_key @api_key end |
#audit_resources ⇒ Object
An array of resource ids that should be included in any audit records generated by requsts made by this instance of the api.
188 189 190 |
# File 'lib/conjur/base.rb', line 188 def audit_resources @audit_resources end |
#audit_roles ⇒ Object
An array of role ids that should be included in any audit records generated by requsts made by this instance of the api.
183 184 185 |
# File 'lib/conjur/base.rb', line 183 def audit_roles @audit_roles end |
#authenticator ⇒ Object (readonly)
Returns the value of attribute authenticator.
390 391 392 |
# File 'lib/conjur/base.rb', line 390 def authenticator @authenticator end |
#privilege ⇒ Object
The optional global privilege (e.g. 'elevate' or 'reveal') which should be attempted on the request.
178 179 180 |
# File 'lib/conjur/base.rb', line 178 def privilege @privilege end |
#remote_ip ⇒ Object (readonly)
An optional IP address to be recorded in the audit record for any actions performed by this API instance.
174 175 176 |
# File 'lib/conjur/base.rb', line 174 def remote_ip @remote_ip end |
Class Method Details
.appliance_health(remote_host = nil) ⇒ Hash
When called without an argument, this method requires a Conjur server running version 4.5 or later. When called with an argument, it requires 4.6 or later.
Return a Hash containing health information for this appliance, or for another host.
If the remote_host
argument is provided, the health of that appliance is reported from
the perspective of the appliance being queried (as specified by the appliance_url
configuration
variable).
83 84 85 |
# File 'lib/conjur/api/info.rb', line 83 def appliance_health remote_host=nil remote_host.nil? ? own_health : remote_health(remote_host) end |
.appliance_info ⇒ Hash
This feature requires Conjur appliance version 4.6 or above.
Return a Hash containing various information about the Conjur appliance.
If the appliance does not support this feature, raise Conjur::FeatureNotAvailable.
66 67 68 69 70 |
# File 'lib/conjur/api/info.rb', line 66 def appliance_info JSON.parse(RestClient::Resource.new(appliance_info_url).get.body) rescue RestClient::ResourceNotFound raise Conjur::FeatureNotAvailable.new('Your appliance does not support the /info URL needed by Conjur::API.appliance_info (you need 4.6 or later)') end |
.authenticate(username, password) ⇒ String
The Conjur authenticate operation exchanges Conjur credentials for a token. The token can then be used to authenticate further API calls.
You will generally not need to use this method, as the API manages tokens automatically for you.
82 83 84 85 86 87 |
# File 'lib/conjur/api/authn.rb', line 82 def authenticate username, password if Conjur.log Conjur.log << "Authenticating #{username}\n" end JSON::parse(RestClient::Resource.new(Conjur::Authn::API.host)["users/#{fully_escape username}/authenticate"].post password, content_type: 'text/plain') end |
.decode_audit_ids(ids) ⇒ Object
160 161 162 |
# File 'lib/conjur/base.rb', line 160 def decode_audit_ids(ids) ids.split('&').collect{|id| CGI::unescape(id)} end |
.encode_audit_ids(ids) ⇒ Object
156 157 158 |
# File 'lib/conjur/base.rb', line 156 def encode_audit_ids(ids) ids.collect{|id| CGI::escape(id)}.join('&') end |
.host_factory_asset_host ⇒ Object
32 33 34 |
# File 'lib/conjur/host-factory-api.rb', line 32 def host_factory_asset_host Conjur.configuration.host_factory_url end |
.host_factory_create_host(token, id, options = {}) ⇒ Object
Creates a host and returns the response Hash.
27 28 29 30 31 32 33 34 |
# File 'lib/conjur/api/host_factories.rb', line 27 def host_factory_create_host token, id, = {} token = token.token if token.is_a?(HostFactoryToken) = { headers: { authorization: %Q(Token token="#{token}") } } response = RestClient::Resource.new(Conjur::API.host_factory_asset_host, )["hosts"].post(.merge(id: id)).body JSON.parse(response) end |
.login(username, password) ⇒ String
The Conjur login operation exchanges a username and a password for an api key. The api key is preferable for storage and use in code, as it can be rotated and has far greater entropy than a user memorizable password.
48 49 50 51 52 53 |
# File 'lib/conjur/api/authn.rb', line 48 def login username, password if Conjur.log Conjur.log << "Logging in #{username} via Basic authentication\n" end RestClient::Resource.new(Conjur::Authn::API.host, user: username, password: password)['users/login'].get end |
.login_cas(username, password, cas_api_url) ⇒ String
This method logs in via CAS. It is similar to the login method, the only difference being that
you need a cas_api_url
, provided by the administrator of your CAS
service.
65 66 67 68 69 70 71 72 |
# File 'lib/conjur/api/authn.rb', line 65 def login_cas username, password, cas_api_url if Conjur.log Conjur.log << "Logging in #{username} via CAS authentication\n" end require 'cas_rest_client' client = CasRestClient.new(:username => username, :password => password, :uri => [ cas_api_url, 'v1', 'tickets' ].join('/'), :use_cookies => false) client.get("#{Conjur::Authn::API.host}/users/login").body end |
.new_from_key(username, api_key, remote_ip = nil) ⇒ Conjur::API
Create a new Conjur::API instance from a username and a password or api key.
107 108 109 |
# File 'lib/conjur/base.rb', line 107 def new_from_key(username, api_key, remote_ip = nil) self.new.init_from_key username, api_key, remote_ip end |
.new_from_token(token, remote_ip = nil) ⇒ Conjur::API
Create a new Conjur::API instance from a token issued by the Conjur authentication service
Generally, you will have a Conjur identitiy (username and api key), and create an Conjur::API instance for the identity using new_from_key. This method is useful when you are performing authorization checks given a token. For example, a Conjur gateway that requires you to prove that you can 'read' a resource named 'super-secret' might get the token from a request header, create an Conjur::API instance with this method, and use Resource#permitted? to decide whether to accept and forward the request.
137 138 139 |
# File 'lib/conjur/base.rb', line 137 def new_from_token(token, remote_ip = nil) self.new.init_from_token token, remote_ip end |
.new_from_token_file(token_file, remote_ip = nil) ⇒ Conjur::API
Create a new Conjur::API instance from a file containing a token issued by the Conjur authentication service. The file is read the first time that a token is required. It is also re-read whenever the API decides that the token it already has is getting close to expiration.
This method is useful when an external process, such as a sidecar container, is continuously obtaining fresh tokens and writing them to a known file.
152 153 154 |
# File 'lib/conjur/base.rb', line 152 def new_from_token_file(token_file, remote_ip = nil) self.new.init_from_token_file token_file, remote_ip end |
.rotate_api_key(username, password) ⇒ String
If the user does not have a password, the returned API key will be the only way to authenticate as the user. Therefore, you'd best save it.
This feature requires version 4.6 of the Conjur appliance.
Rotate the currently authenticated user's API key by generating and returning a new one. The old API key is no longer valid after calling this method. You must have the user's current API key or password to perform this operation. This method does not affect the user's password.
121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/conjur/api/authn.rb', line 121 def rotate_api_key username, password if Conjur.log Conjur.log << "Rotating API key for self (#{username})\n" end RestClient::Resource.new( Conjur::Authn::API.host, user: username, password: password )['users/api_key'].put('').body end |
.service_names ⇒ Array<String>
Return an Array of valid service names for your appliance.
55 56 57 |
# File 'lib/conjur/api/info.rb', line 55 def service_names appliance_info['services'].keys end |
.service_version(service) ⇒ Semantic::Version
Return the version of the given service presently running on the Conjur appliance.
This feature is useful for determining whether the Conjur appliance has a particular feature.
If the given service does not exist, this method will raise an exception. To retrieve a list of
valid service names, you can use Conjur::API.service_names
40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/conjur/api/info.rb', line 40 def service_version service if (service_info = appliance_info['services'][service]).nil? raise "Unknown service #{service} (services are #{service_names.join(', ')}." else # Pre-release versions are discarded, because they make testing harder: # 2.0.0-p598 :004 > Semantic::Version.new("4.5.0") <= Semantic::Version.new("4.5.0-1") # => false major, minor, patch, pre = service_info['version'].split(/[.-]/)[0..3] Semantic::Version.new "#{major}.#{minor}.#{patch}" end end |
.update_password(username, password, new_password)
This method returns an undefined value.
Change a user's password. To do this, you must have the user's current password. This does not change or rotate api keys. However, you can use the user's api key as the current password, if the user was not created with a password.
98 99 100 101 102 103 |
# File 'lib/conjur/api/authn.rb', line 98 def update_password username, password, new_password if Conjur.log Conjur.log << "Updating password for #{username}\n" end RestClient::Resource.new(Conjur::Authn::API.host, user: username, password: password)['users/password'].put new_password end |
Instance Method Details
#add_public_key(username, key) ⇒ Object
Add an SSH public key for username
.
Key Format
This method will raise an exception if key
is not of the format
"<algorithm> <data> <name>"
(that is, key.split(\s+)).length must be 3). The <name>
field is used by the service
to identify individual keys for a user.
Permissions
You must have permission to 'update'
the pubkeys service resource. When the Conjur appliance
is configured, it creates the pubkeys service resource with this identifier
'<organizational account>:service:pubkeys-1.0/public-keys'
.
Rather than granting permissions to this resource directly to user roles, we recommend that you add them to the 'key-managers' group, whose unqualified identifier is 'pubkeys-1.0/key-managers', which has permission to add public keys.
Hiding Existence
Because attackers could use this method to determine the existence of Conjur users, it will not raise an error if the user does not exist.
134 135 136 |
# File 'lib/conjur/api/pubkeys.rb', line 134 def add_public_key username, key public_keys_resource(username).post key end |
#audit(options = {}, &block) ⇒ Array<Hash>
Return up to 100 audit events visible to the current authorized role.
An audit event is visible to a role if that role or one of it's ancestors is in the
event's :roles
field, or the role has a privilege any of the event's :resources
field.
43 44 45 |
# File 'lib/conjur/api/audit.rb', line 43 def audit ={}, &block audit_event_feed "", , &block end |
#audit_resource(resource, options = {}, &block) ⇒ Array<Hash>
Return up to 100 audit events visible to the current role and related to the given resource.
See #audit for the conditions under which an event is visible to a role.
An event is said to be "related to" a role iff the role is a member of the event's
:roles
field.
83 84 85 |
# File 'lib/conjur/api/audit.rb', line 83 def audit_resource resource, ={}, &block audit_event_feed "resources/#{CGI.escape cast(resource, :resourceid)}", , &block end |
#audit_role(role, options = {}, &block) ⇒ Array<Hash>
Return up to 100 audit events visible to the current role and related to the given role.
See #audit for the conditions under which an event is visible to a role.
An event is said to be "related to" a role iff the role is a member of the event's
:roles
field.
63 64 65 |
# File 'lib/conjur/api/audit.rb', line 63 def audit_role role, ={}, &block audit_event_feed "roles/#{CGI.escape cast(role, :roleid)}", , &block end |
#audit_send(input) ⇒ Object
Send custom audit event
89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/conjur/api/audit.rb', line 89 def audit_send input json = if input.kind_of? String input elsif input.kind_of? Array or input.kind_of? Hash input.to_json else raise ArgumentError, "Parameter should be either String, Hash or Array" end rest_api = RestClient::Resource.new(Conjur::Authz::API.host, credentials)["audit"] rest_api.post json, content_type: "text/plain" end |
#bootstrap(listener) ⇒ Object
Perform all commands in Conjur::Bootstrap::Command.
199 200 201 202 203 204 205 |
# File 'lib/conjur/base.rb', line 199 def bootstrap listener Conjur::Bootstrap::Command.constants.map{|c| Conjur::Bootstrap::Command.const_get(c)}.each do |cls| next unless cls.is_a?(Class) next unless cls.superclass == Conjur::Bootstrap::Command::Base cls.new(self, listener).perform end end |
#create_deputy(options = {}) ⇒ Conjur::Deputy
Create a Conjur deputy.
Deputies are used internally by Conjur services that need to perform actions as a particular role. While the deputies API is stable, it isn't intended for use by end users.
40 41 42 |
# File 'lib/conjur/api/deputies.rb', line 40 def create_deputy = {} standard_create Conjur::Core::API.host, :deputy, nil, end |
#create_group(id, options = {}) ⇒ Conjur::Group
Create a new group with the given identifier.
Groups can be created with a gidnumber attribute, which is used when mapping LDAP/ActiveDirectory groups to Conjur groups, and when performing PAM authentication to assign a unix GID.
69 70 71 |
# File 'lib/conjur/api/groups.rb', line 69 def create_group(id, = {}) standard_create Conjur::Core::API.host, :group, id, end |
#create_host(options = nil) ⇒ Conjur::Host
Create a new host
asset.
By default this method will create a host with a random id. However, you may create a host with a
specific name by passing an :id
option.
Permissions
- Any Conjur role may perform this method without an
:ownerid
option. The new hosts owner will be the current role. - If you pass an `
:ownerid
option, you must be a member of the given role.
80 81 82 83 84 |
# File 'lib/conjur/api/hosts.rb', line 80 def create_host = nil = .merge \ cidr: [*[:cidr]].map(&CIDR.method(:validate)).map(&:to_s) if [:cidr] standard_create Conjur::Core::API.host, :host, nil, end |
#create_host_factory(id, options = {}) ⇒ Object
Options: +layers+ list of host factory layers +roleid+ host factory role id +role+ host factory role. If this is provided, it is converted to roleid.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/conjur/api/host_factories.rb', line 41 def create_host_factory(id, = {}) if [:layers] [:layers] = [:layers].map do |layer| if layer.is_a?(Conjur::Layer) layer.id elsif layer.is_a?(String) layer else raise "Can't interpret layer #{layer}" end end end if role = .delete(:role) [:roleid] = role.roleid end log do |logger| logger << "Creating host_factory #{id}" unless .blank? logger << " with options #{.to_json}" end end ||= {} [:id] = id resp = RestClient::Resource.new(Conjur::API.host_factory_asset_host, credentials).post() Conjur::HostFactory.build_from_response(resp, credentials) end |
#create_layer(id, options = {}) ⇒ Conjur::Layer
Create a new layer with the given id
22 23 24 |
# File 'lib/conjur/api/layers.rb', line 22 def create_layer(id, = {}) standard_create Conjur::API.layer_asset_host, :layer, id, end |
#create_resource(identifier, options = {}) ⇒ Conjur::Role
Create a Conjur Resource. Resources are entities on which roles have permissions. A resource might represent a secret, a web service route, or be part of a higher level construct such as a user or group.
If :acting_as
is not present in options
, you will be the owner of the new role. If it is present,
your role must be a member of the given role (see Role#member_of?).
57 58 59 60 61 |
# File 'lib/conjur/api/resources.rb', line 57 def create_resource(identifier, = {}) resource(identifier).tap do |r| r.create() end end |
#create_role(role, options = {}) ⇒ Conjur::Role
Create a Role with the given id.
Permissions
- All Conjur roles can create new roles.
- The creator role (either the current role or the role given by the
:acting_as
option) is made a member of the new role. The new role is also made a member of itself. - If you give an
:acting_as
option, you must be a (transitive) member of the:acting_as
role. - The new role is granted to the creator role with admin option: that is, the creator role is able to grant the created role to other roles.
79 80 81 82 83 |
# File 'lib/conjur/api/roles.rb', line 79 def create_role(role, = {}) role(role).tap do |r| r.create() end end |
#create_user(login, options = {}) ⇒ Conjur::User
Create a Conjur User. Conjur users are identities for humans.
When you create a user for the first time, the returned object will have an api_key
field. You can then
use this to set a password for the user if you want to. Note that when the user is fetched later with the #user
method, it will not have an api_key. Use it or lose it.
Permissions
Any authenticated role may call this method.
59 60 61 62 63 |
# File 'lib/conjur/api/users.rb', line 59 def create_user(login, = {}) = .merge \ cidr: [*[:cidr]].map(&CIDR.method(:validate)).map(&:to_s) if [:cidr] standard_create Conjur::Core::API.host, :user, nil, .merge(login: login) end |
#create_variable(mime_type, kind, options = {}) ⇒ Conjur::Variable
Create a Conjur Variable. See Variable for operations on Conjur variables.
Permissions
Any authenticated role may call this method
57 58 59 |
# File 'lib/conjur/api/variables.rb', line 57 def create_variable(mime_type, kind, = {}) standard_create Conjur::Core::API.host, :variable, nil, .merge(mime_type: mime_type, kind: kind) end |
#credentials ⇒ Hash
Credentials that can be merged with options to be passed to RestClient::Resource
HTTP request methods.
These include a username and an Authorization header containing the authentication token.
231 232 233 234 235 236 237 238 239 240 |
# File 'lib/conjur/base.rb', line 231 def credentials headers = {}.tap do |h| h[:authorization] = "Token token=\"#{Base64.strict_encode64 token.to_json}\"" h[:x_conjur_privilege] = @privilege if @privilege h[:x_forwarded_for] = @remote_ip if @remote_ip h[:conjur_audit_roles] = Conjur::API.encode_audit_ids(@audit_roles) if @audit_roles h[:conjur_audit_resources] = Conjur::API.encode_audit_ids(@audit_resources) if @audit_resources end { headers: headers, username: username } end |
#current_role ⇒ Conjur::Role
Return a Role object representing the role (typically a user or host) that this api is authenticated
as. This is derived either from the login
argument to new_from_key or from the contents of the
token
given to new_from_token.
130 131 132 |
# File 'lib/conjur/api/roles.rb', line 130 def current_role role_from_username username end |
#delete_public_key(username, keyname)
This method returns an undefined value.
Delete a specific public key for a user.
Permissions
You must have permission to 'update'
the pubkeys service resource. When the Conjur appliance
is configured, it creates the pubkeys service resource with this identifier
'<organizational account>:service:pubkeys-1.0/public-keys'
.
Rather than granting permissions to this resource directly to user roles, we recommend that you add them to the 'key-managers' group, whose unqualified identifier is 'pubkeys-1.0/key-managers', which has permission to add public keys.
Hiding Existence
Because attackers could use this method to determine the existence of Conjur users, it will not raise an error if the user does not exist.
166 167 168 |
# File 'lib/conjur/api/pubkeys.rb', line 166 def delete_public_key username, keyname public_keys_resource(username, keyname).delete end |
#deputy(id) ⇒ Conjur::Deputy
Find a Conjur deputy by id. Deputies are used internally by Conjur services that need to perform actions as a particular role. While the deputies API is stable, it isn't intended for use by end users.
53 54 55 |
# File 'lib/conjur/api/deputies.rb', line 53 def deputy id standard_show Conjur::Core::API.host, :deputy, id end |
#find_groups(options) ⇒ Array<String>
Find groups by GID. Note that gidnumbers are not unique for groups.
106 107 108 |
# File 'lib/conjur/api/groups.rb', line 106 def find_groups JSON.parse(RestClient::Resource.new(Conjur::Core::API.host, credentials)["groups/search?#{.to_query}"].get) end |
#global_privilege_permitted?(privilege) ⇒ Boolean
Checks whether the client has a particular global privilege. The global privileges are elevate and reveal.
171 172 173 |
# File 'lib/conjur/api/resources.rb', line 171 def global_privilege_permitted? privilege resource(GLOBAL_PRIVILEGE_RESOURCE).permitted? privilege end |
#group(id) ⇒ Conjur::Group
Fetch a group with the given id. Note that the id is unqualified -- it must not contain
account
or id
parts. For example,
87 88 89 |
# File 'lib/conjur/api/groups.rb', line 87 def group id standard_show Conjur::Core::API.host, :group, id end |
#groups(options = {}) ⇒ Array<Conjur::Group>
List all Conjur groups visible to the current role. This method does not
support advanced query options. If you want those, use #resources
with
the :kind
option set to 'group'
.
37 38 39 |
# File 'lib/conjur/api/groups.rb', line 37 def groups(={}) standard_list Conjur::Core::API.host, :group, end |
#host(id) ⇒ Conjur::Host
Get a host by its unqualified id.
Like other Conjur methods, this will return a Host whether or not the record is found, and you must use the Exists#exists? method to check this.
210 211 212 |
# File 'lib/conjur/base.rb', line 210 def host self.class.host end |
#host_factory(id) ⇒ Object
68 69 70 |
# File 'lib/conjur/api/host_factories.rb', line 68 def host_factory id Conjur::HostFactory.new(Conjur::API.host_factory_asset_host, credentials)[fully_escape(id)] end |
#host_factory_create_host(token, id, options = {}) ⇒ Object
Creates a Host and returns a Host object.
86 87 88 89 90 91 |
# File 'lib/conjur/api/host_factories.rb', line 86 def host_factory_create_host token, id, = {} attributes = self.class.host_factory_create_host token, id, Conjur::Host.new(Conjur::API.core_asset_host, credentials)["hosts"][fully_escape attributes['id']].tap do |host| host.attributes = attributes end end |
#init_from_key(username, api_key, remote_ip = nil) ⇒ Object
369 370 371 372 373 374 375 |
# File 'lib/conjur/base.rb', line 369 def init_from_key username, api_key, remote_ip = nil @username = username @api_key = api_key @remote_ip = remote_ip @authenticator = APIKeyAuthenticator.new(username, api_key) self end |
#init_from_token(token, remote_ip = nil) ⇒ Object
377 378 379 380 381 382 |
# File 'lib/conjur/base.rb', line 377 def init_from_token token, remote_ip = nil @token = token @remote_ip = remote_ip @authenticator = UnableAuthenticator.new self end |
#init_from_token_file(token_file, remote_ip = nil) ⇒ Object
384 385 386 387 388 |
# File 'lib/conjur/base.rb', line 384 def init_from_token_file token_file, remote_ip = nil @remote_ip = remote_ip @authenticator = TokenFileAuthenticator.new(token_file) self end |
#layer(id) ⇒ Conjur::Layer
Get a layer by its unqualified id.
Like other Conjur methods, this will return a Layer whether or not the record is found, and you must use the Exists#exists? method to check this.
56 57 58 |
# File 'lib/conjur/api/layers.rb', line 56 def layer id standard_show Conjur::API.layer_asset_host, :layer, id end |
#layers(options = {}) ⇒ Array<Conjur::Layer>
Get all layers visible to the current role.
The options
parameter is only included for backwards
compatibility and has no effect. You should call this method
without arguments.
34 35 36 |
# File 'lib/conjur/api/layers.rb', line 34 def layers ={} standard_list Conjur::API.layer_asset_host, :layer, end |
#ldap_sync_policy(profile, options = {}) ⇒ Object
Fetch a Conjur policy that will bring Conjur into sync with the LDAP server specified by a profile.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/conjur/api/ldapsync.rb', line 32 def ldap_sync_policy profile, = {} headers = credentials.dup.tap {|h| h[:headers][:accept] = 'text/event-stream' } = .merge(:config_name => profile) url = Conjur.configuration.appliance_url + "/ldap-sync/policy?#{.to_query}" # Even though we're using SSE to return the policy, fetch the # whole thing at once into a single response. Retrieving it in # chunks doesn't buy us much of anything except more complicated # client code. response = RestClient::Resource.new(url, headers).get JSON.parse(get_json("policy", response)).merge('events' => find_log_events(response)) end |
#ldap_sync_show_profile(profile, options = {}) ⇒ Object
54 55 56 57 58 |
# File 'lib/conjur/api/ldapsync.rb', line 54 def ldap_sync_show_profile(profile, = {}) url = Conjur.configuration.appliance_url resp = RestClient::Resource.new(url, credentials)['ldap-sync']['config'][profile].get() JSON.parse(resp.body) end |
#public_key(username, keyname) ⇒ String
Fetch a specific key by name. The key name is the last token in the public key itself,
typically formatted as '<login>@<hostname>'
.
Permissions
You do not need any special permissions to call this method, since public keys are, well, public.
69 70 71 |
# File 'lib/conjur/api/pubkeys.rb', line 69 def public_key username, keyname public_keys_resource(username, keyname).get end |
#public_key_names(username) ⇒ Array<String>
List the public key names for the given user.
If the given user does not exist, an empty Array will be returned. This is to prevent attackers from determining whether a user exists.
Permissions
You do not need any special permissions to call this method, since public keys are, well, public.
94 95 96 |
# File 'lib/conjur/api/pubkeys.rb', line 94 def public_key_names username public_keys(username).lines.map{|s| s.split(' ')[-1]} end |
#public_keys(username) ⇒ String
Fetch all public keys for the user. This method returns a newline delimited String for compatibility with the authorized_keys SSH format.
If the given user does not exist, an empty String will be returned. This is to prevent attackers from determining whether a user exists.
Permissions
You do not need any special permissions to call this method, since public keys are, well, public.
45 46 47 |
# File 'lib/conjur/api/pubkeys.rb', line 45 def public_keys username public_keys_resource(username).get end |
#resource(identifier) ⇒ Conjur::Resource
Find a resource by it's id. The id given to this method must be qualified by a kind, but the account is optional.
Permissions
The resource must be visible to the current role. This is the case if the current role is the owner of the resource, or has any privilege on it.
86 87 88 |
# File 'lib/conjur/api/resources.rb', line 86 def resource identifier Resource.new(Conjur::Authz::API.host, credentials)[self.class.parse_resource_id(identifier).join('/')] end |
#resources(opts = {}) ⇒ Array<Conjur::Resource>
Find all resources visible to the current role that match the given search criteria.
Full Text Search
Conjur supports full text search over the identifiers and annotation values
of resources. For example, if opts[:search]
is "pubkeys"
, any resource with
an id containing "pubkeys"
or an annotation whose value contains "pubkeys"
will match.
Notes
- Annotation keys are not indexed for full text search.
- Conjur indexes the content of ids and annotation values by word.
- Only resources visible to the current role (either owned by that role or having a privilege on it) are returned.
- If you do not provide
:offset
or:limit
, all records will be returned. For systems with a huge number of resources, you may want to paginate as shown in the example below. - If
:offset
is provided and:limit
is not, 10 records starting at:offset
will be returned. You may choose an arbitrarily large number for:limit
, but the same performance considerations apply as when omitting:offset
and:limit
.
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/conjur/api/resources.rb', line 140 def resources opts = {} opts = { host: Conjur::Authz::API.host, credentials: credentials }.merge opts opts[:account] ||= Conjur.account result = Resource.all(opts) if result.is_a?(Numeric) result else result.map do |result| resource(result['id']).tap do |r| r.attributes = result end end end end |
#resources_permitted?(kind, identifiers, privilege) ⇒ Array
Returns first element is a Boolean, true if all checks passed, false otherwise. If some checks fail, second element is the check result for each resource.
188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/conjur/api/resources.rb', line 188 def resources_permitted? kind, identifiers, privilege = { privilege: privilege, identifiers: identifiers } resp = RestClient::Resource.new(Conjur::Authz::API.host, credentials)["#{Conjur.account}/resources/#{kind}?check=true"].post() if resp.code == 204 [true, []] else [false, JSON.parse(resp.body)] end end |
#revoke_host_factory_token(token) ⇒ Object
72 73 74 75 |
# File 'lib/conjur/api/host_factories.rb', line 72 def revoke_host_factory_token token token = token.token if token.is_a?(Conjur::HostFactoryToken) RestClient::Resource.new(Conjur::API.host_factory_asset_host, credentials)["tokens/#{token}"].delete end |
#role(role) ⇒ Conjur::Role
Return a Role representing a role with the given id. Note that the Role may or may not exist (see Exists#exists?).
Permissions
Because this method returns roles that may or may not exist, it doesn't require any permissions to call it: in fact, it does not perform an HTTP request (except for authentication if necessary).
110 111 112 |
# File 'lib/conjur/api/roles.rb', line 110 def role role Role.new(Conjur::Authz::API.host, credentials)[self.class.parse_role_id(role).join('/')] end |
#role_graph(roles, options = {}) ⇒ Conjur::Graph
Fetch a Graph representing the relationships of a given role or roles. Such graphs are transitive, and follow the normal permissions for role visibility.
38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/conjur/api/roles.rb', line 38 def role_graph roles, = {} roles = [roles] unless roles.kind_of? Array roles.map!{|r| normalize_roleid(r) } [:as_role] = normalize_roleid([:as_role]) if .include?(:as_role) .reverse_merge! as_role: normalize_roleid(current_role), descendants: true, ancestors: true query = {from_role: .delete(:as_role)} .merge(.slice(:ancestors, :descendants)) .merge(roles: roles).to_query Conjur::Graph.new RestClient::Resource.new(Conjur::Authz::API.host, credentials)["#{Conjur.account}/roles?#{query}"].get end |
#show_host_factory_token(token) ⇒ Object
77 78 79 80 81 82 83 |
# File 'lib/conjur/api/host_factories.rb', line 77 def show_host_factory_token token token = token.token if token.is_a?(Conjur::HostFactoryToken) attrs = JSON.parse(RestClient::Resource.new(Conjur::API.host_factory_asset_host, credentials)["tokens/#{token}"].get.body) Conjur::HostFactoryToken.new(Conjur::API.host_factory_asset_host, credentials)["tokens"][attrs['token']].tap do |token| token.attributes = attrs end end |
#token ⇒ Hash
The token used to authenticate requests made with the api. The token will be fetched, if possible, when not present or about to expire. Accordingly, this method may raise a RestClient::Unauthorized exception if the credentials are invalid.
220 221 222 223 |
# File 'lib/conjur/base.rb', line 220 def token refresh_token if needs_token_refresh? return @token end |
#user(login) ⇒ Conjur::User
Return an object representing a user with the given login. The User object returned may or may not exist. You can check whether it exists with the Exists#exists? method.
The returned User will not have an api_key.
Permissions
Any authenticated role may call this method.
75 76 77 |
# File 'lib/conjur/api/users.rb', line 75 def user login standard_show Conjur::Core::API.host, :user, login end |
#username ⇒ String
The name of the user as which this api instance is authenticated. This is available whether the api instance was created from credentials or an authentication token.
194 195 196 |
# File 'lib/conjur/base.rb', line 194 def username @username || @token['data'] end |
#variable(id) ⇒ Conjur::Variable
Retrieve an object representing a Conjur Variable. The Variable returned may or may not exist, and your permissions on the corresponding resource determine the operations you can perform on it.
Permissions
Any authenticated role can call this method.
70 71 72 |
# File 'lib/conjur/api/variables.rb', line 70 def variable id standard_show Conjur::Core::API.host, :variable, id end |
#variable_expirations(interval = nil) ⇒ Object
param interval a String containing an ISO8601 duration , or a number of seconds return [Hash] variable expirations that occur within the interval
126 127 128 129 130 |
# File 'lib/conjur/api/variables.rb', line 126 def variable_expirations(interval = nil) duration = interval.try { |i| i.respond_to?(:to_str) ? i : "PT#{i.to_i}S" } params = {}.tap { |p| p.merge!({:params => {:duration => duration }}) if duration } JSON.parse(RestClient::Resource.new(Conjur::Core::API.host, self.credentials)['variables/expirations'].get(params).body) end |
#variable_values(varlist) ⇒ Hash
Fetch the values of a list of variables. This operation is more efficient than fetching the values one by one.
This method will fail unless:
- All of the variables exist
- You have permission to
'execute'
all of the variables
This method is used to implement the conjur env
commands. You may consider using that instead to run your program in an environment with the necessary secrets.
96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/conjur/api/variables.rb', line 96 def variable_values(varlist) raise ArgumentError, "Variables list must be an array" unless varlist.kind_of? Array raise ArgumentError, "Variables list is empty" if varlist.empty? opts = "?vars=#{varlist.map { |v| fully_escape(v) }.join(',')}" begin resp = RestClient::Resource.new(Conjur::Core::API.host, self.credentials)['variables/values'+opts].get return JSON.parse( resp.body ) rescue RestClient::ResourceNotFound return Hash[ *varlist.map { |v| [ v, variable(v).value ] }.flatten ] end end |
#with_audit_resources(resource_ids) ⇒ Object
259 260 261 262 263 264 265 |
# File 'lib/conjur/base.rb', line 259 def with_audit_resources resource_ids resource_ids = Array(resource_ids) self.clone.tap do |api| # Ensure that all resource ids are fully qualified api.audit_resources = resource_ids.collect { |id| api.resource(id).resourceid } end end |
#with_audit_roles(role_ids) ⇒ Object
251 252 253 254 255 256 257 |
# File 'lib/conjur/base.rb', line 251 def with_audit_roles role_ids role_ids = Array(role_ids) self.clone.tap do |api| # Ensure that all role ids are fully qualified api.audit_roles = role_ids.collect { |id| api.role(id).roleid } end end |
#with_privilege(privilege) ⇒ Object
Return a new API object with the specified X-Conjur-Privilege.
245 246 247 248 249 |
# File 'lib/conjur/base.rb', line 245 def with_privilege privilege self.clone.tap do |api| api.privilege = privilege end end |