Skip to main content

Targets and devices

A target is the machine a privileged secret opens. The ten platform types, what connection detail each needs, and what the connection test really proves.

Written for whoever runs IT9 min readUpdated

A target is the machine a privileged secret opens: a server, a database, a switch, a firewall, a cloud account. It is the first object you create in the privileged access module, and everything else depends on it. This article covers what a target records, the ten platform types Qorionix manages, exactly what connection detail each one needs, and what the connection test does and does not prove.

The reason targets exist as a separate object is worth a paragraph, because it explains a behaviour you will otherwise find surprising. Earlier in the product's life, a vault entry was a name, a type and an encrypted blob. Nothing on it said what the secret opened. The consequence was that an administrator could add a secret, set a thirty-day rotation interval, and have nothing rotate — not because rotation was broken, but because the record binding a credential to a machine did not exist, so there was no address to connect to. A credential with no target is now reported as such, in those words, rather than appearing to be scheduled.

What a target records

The fields are deliberately few. A target is an address, not a configuration management database.

`hostname` and `port`
Where Qorionix connects. The hostname is an address only — enter db01.example.internal, not https://db01.example.internal/admin. The port defaults to the platform's usual one and must be between 0 and 65535.
`platform`
One of the ten strings in the table below. This single field determines the default port, which credential types are allowed, which extra connection detail is required, and which rotation engine will be used. Choosing it wrongly is the most common cause of a rotation that cannot be enabled.
`name`, `description`, `environment`
For humans. The name defaults to the hostname. The environment is lower-cased and defaults to production, which is a deliberately cautious default: a target you did not label is treated as one that matters.
`metadata`
A flat map of strings carrying the platform-specific connection detail — the WinRM endpoint, the domain controller, the database name, the AWS region. Never put a secret in metadata. It is not encrypted and it is returned by the API.

Three further fields are derived rather than entered: the platform's display name, the number of credentials attached to the target, and the result of the last connection test.

The ten platform types

The catalogue is compiled into the product rather than configurable, and the reason is stated in the code itself: only combinations that actually work are listed. Offering MySQL here, when there is no MySQL rotation engine behind it, would let you build a schedule that can only ever fail. A short true list beats a long false one.

The ten platform values, verbatim as stored in the target record, with the connection detail each requires and whether Qorionix can sign in to verify a credential of that kind.
`platform` valueShown asDefault portCredential types allowedRequired metadataRotation engineCan be verified by signing in
linuxLinux server22password, ssh_key—linux_ssh (password only)Yes
windowsWindows server5985passwordwinrm_endpointwindows_localNo
active_directoryActive Directory389passworddomain_controllerad_service_accountNo
postgresqlPostgreSQL5432passworddatabase, sslmodepostgres_roleYes
sqlserverSQL Server1433passworddatabasesqlserver_loginYes
cisco_iosCisco IOS switch or router22passwordenable_secretcisco_iosYes
panosPalo Alto firewall443password—paloalto_panosNo
awsAWS account443api_tokenregionaws_iam_keyNo
entra_idMicrosoft Entra ID443api_tokentenant_id, object_identra_service_principalNo
genericOther (no rotation)0password, api_token, ssh_key, certificate—NoneNo

Every platform except generic can be rotated. generic is the honest bucket for a secret that matters but that Qorionix has no engine for — a SaaS admin password, a certificate, an API token for something obscure. Storing it in the vault with a target still buys you a single place, an audit record and access control. It does not buy you rotation, and the credential will say so.

Creating a target

  1. Enter the address, without a scheme or a path

    Just dc01.example.internal or an IP address. If you paste a URL you will get enter just the address, without http:// or a path and nothing will be created.

  2. Choose the platform

    From the table above. The value is lower-cased and looked up in the catalogue, so a typo produces a list of the ten valid values rather than a generic rejection.

  3. Accept or override the port

    The default comes from the platform. Override it where your estate differs — a Windows target using HTTPS WinRM on 5986, a PostgreSQL instance behind a pooler on 6432.

  4. Fill in the required metadata for that platform

    The right-hand column of the table. This is the part people skip, and it is the part rotation fails on later: a Windows target with no winrm_endpoint will be given the fallback https://<host>:5986/wsman, which is correct in many estates and wrong in yours if WinRM is on the plaintext port.

  5. Label the environment

    Lower-cased, defaulting to production. Worth setting honestly, because it is what lets an access policy treat a test box differently from the finance database.

  6. Run the connection test

    Before you attach any credential you care about. What the test proves varies by platform, and the next section is entirely about that.

Every create, update, delete and test writes a hash-chained audit row — pam.target.create, pam.target.update, pam.target.delete, pam.target.test. Chained means each row commits to the one before it, so a row cannot be removed from the middle of the history without the chain failing to verify.

The exact refusals

All four of these return HTTP 400 and nothing is created. The %q, %s and %d are filled in with the value you supplied.

Verbatim validation errors when creating or updating a target
an address or hostname is required
enter just the address, without http:// or a path
%q is not a platform Qorionix manages; choose one of active_directory, aws,
  cisco_ios, entra_id, generic, linux, panos, postgresql, sqlserver, windows
%d is not a valid port

Two more are conflicts rather than validation errors, and both return HTTP 409:

a target for %s on port %d already exists
Creating a second target on the same address, port and platform
this target still has %d credential(s) attached; move or delete them first
Deleting a target that credentials still point at

The delete refusal is deliberate and we are not going to soften it. The database could have been set up to null the link instead, which would let the delete succeed — and would quietly turn every credential on that machine into an unbound one, still in the vault, still holding a real password, no longer rotating and no longer describing anything. A refusal you have to act on is better than a success that degrades your inventory.

Renaming a host is safe: the new address propagates to the target's rotation schedules in the same operation. Without that, the next scheduled run would go on connecting to the old address and failing, and the failure would be a mystery because the console would be showing the new name.

What the connection test actually checks

The test has one design rule that shapes everything about how it reports: an unreachable host and a rejected password are outcomes of a test that worked. Both return HTTP 200 with a result. The request only errors when the test could not be attempted at all. So a red result in the console is information, not a broken feature.

You can test with a credential already in the vault, or with a secret supplied inline for a target you are still setting up. Either way the secret is never logged, never written to the audit row and never returned in the response.

The five outcome values a connection test can return, verbatim, and what each one means.
`outcome`What it means
okQorionix reached the target and authenticated as the account. This is the only outcome that counts as verified.
unreachableThe network did not deliver us to the service. Address, port or firewall.
auth_failedThe service answered and rejected the credential. The stored secret is not the one the target expects.
unsupportedQorionix has no verifier or adapter for this combination. This is a product gap on our side, not a misconfiguration on yours.
errorEverything else, including a permission problem after a successful sign-in.

How deep the test goes, per platform

Four of the ten platforms get a real sign-in. The rest get a TCP probe, and the result says so in words rather than implying more than it did.

  • linux and cisco_ios — a genuine SSH password login, and then a session is opened without running any command. The session matters: an account whose shell is /sbin/nologin will authenticate happily and then be useless for rotation, so authentication alone would be a misleading pass.
  • postgresql — a real connection followed by SELECT 1. Port defaults to 5432, database to postgres, sslmode to prefer. If admin_user and admin_password are present in the target's metadata they are used instead of the credential itself.
  • sqlserver — a TDS login and nothing else; no statement is run. Port defaults to 1433, and trust_server_certificate defaults to true, which is worth knowing if your instance presents a certificate you would rather have validated.
  • Everything else — windows, active_directory, aws, entra_id, panos, generic — is a TCP probe. Qorionix learns that something is listening. It does not learn that your password is correct.

Host keys are not pinned on the SSH paths. The test accepts whatever key the host presents. That is a known limitation rather than an oversight: verifying the host key more strictly in the test than the rotation engine does would produce tests that pass and rotations that fail, which is the worst of both. Host-key pinning is separate work.

The sentences the test writes

These are the exact strings that land in the test detail and in the console. Search for the one you saw.

Success
Connected to %s on port %d and signed in as %q.
Connected to %s on port %d.
Unreachable
Could not reach %s on port %d. The host did not answer, so check the address,
  the port, and any firewall between Qorionix and it.
Could not reach the target. Check that the address is correct and that Qorionix
  is allowed to connect to it.
The credential was rejected
%s answered, but rejected the credential for %q. The password or key stored here
  is not the one the target expects.
%s answered, but rejected the credential. The password or key stored here is not
  the one the target expects.
The target rejected the credential. The password or key stored here is not the one
  it expects.
Qorionix could not check, and says so
Qorionix cannot test this kind of credential on %s yet. It will be stored, but not
  verified.
%s is listening on port %d. Qorionix cannot sign in to check the credential itself
  on this platform, so it will be stored unverified.
%s is listening on port %d. Qorionix can rotate this credential but cannot sign in
  to check it beforehand, so it will be stored unverified.
Signed in, but the operation did not complete
Connected to %s as %q, but the operation did not complete. The account may not
  have permission to change its own password.

What to do next

  1. Add the secret to the vault and attach it to the target you just created.
  2. Turn on rotation once the connection test returns ok — and only then.
  3. Let discovery find the accounts you forgot on the targets you have registered.

Was this article wrong?

If a procedure here does not match what you see, or a limit we described has changed, tell us and we will fix the page. Email us about this article, or see how to get help if you need an answer rather than a correction.

Everything in privileged access