Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Reports

Impact, owners and connection checks.

GET /api/v1/certificates

Every certificate the engine connects to, as its last check saw it (read even when this server doesn't trust them), every one it presents (side: ours, as loaded), and when the engine checks next by itself.

Who may call it: anyone signed in (a person or a token).

Answers

GET /api/v1/docs

The company-defined documentation fields and every interface's, destination's and resource's values. Read-only: the project's files are the source of truth.

Who may call it: anyone signed in (a person or a token).

Answers

POST /api/v1/doctor

Check every connection the engine needs, from its server: DNS, TCP (with the address a firewall request needs), TLS (certificate, expiry), then each system's own login; also the alerts' mail server, webhooks and heartbeat. Never sends anything to a destination. Listening ports aren't checked (the engine holds them). The run is kept (/doctor/runs), and the certificates it saw (/certificates). Operator.

Who may call it: an operator or admin.

Body (application/json): DoctorRequest

Answers

GET /api/v1/doctor/runs

The connection checks kept (the last 30), newest first. Operator.

Who may call it: an operator or admin.

Answers

GET /api/v1/doctor/runs/{id}

One kept connection check's report, as POST /doctor returned it. Operator.

Who may call it: an operator or admin.

Parameters

InType
id (required)pathnumberThe run's id.

Answers

GET /api/v1/impact

Which interfaces a vendor, application or host touches, how, and who owns them (for a vendor breach or a VPN/IP change). Exactly one of vendor, application, host.

Who may call it: anyone signed in (a person or a token).

Parameters

InType
vendorquerytexte.g. Epic Systems (ignores case).
applicationquerytexte.g. Sunquest Lab (ignores case).
hostquerytextAn address, subnet (10.20.30.0/24) or host name.
resolvequerytrue or falseLook host names up in DNS (from the engine's server), so names and addresses match.

Answers

GET /api/v1/owners

Who owns which interface (about.owner), destination (owner on one someone else owns) and resources.yaml entry, and whether each owner is an account (username, email or display name, ignoring case, or one it had before), a team in owners:, or nobody the engine knows.

Who may call it: anyone signed in (a person or a token).

Answers

GET /api/v1/owners/people

The accounts that can own things (enabled ones), for choosing a new owner: name and email.

Who may call it: anyone signed in (a person or a token).

Answers

POST /api/v1/owners/reassign/preview

What moving ownership from one owner to another would change, as ductus owners reassign --dry-run shows it, plus a patch to apply in the project's repository. Writes nothing: the interfaces' files are the project's (in git), so the change is made there and deployed. Reads the files as they are on the engine's server now.

Who may call it: anyone signed in (a person or a token).

Body (application/json): ReassignRequest

Answers

GET /api/v1/ports

What the engine listens on and connects to, with TLS in and out: the same report as ductus ports.

Who may call it: anyone signed in (a person or a token).

Answers

Shapes

The JSON bodies the operations above take and return.

AllowedName

FieldType
addresseslist of textThe addresses let in for it: the last lookup that found some (kept when a later one fails).
checked_at (optional)time (RFC 3339) or nullWhen it was last looked up.
error (optional)text or nullWhy the last lookup failed, if it did.
nametext

CertificateInfo

FieldType
alert (optional)number or nullIts alert (/alerts/{id}), when alerts are set up.
chain_earliest (optional)text or nullWhose that is, when it isn't the server certificate's (an intermediate).
chain_not_after (optional)time (RFC 3339) or nullThe earliest expiry in its chain (what counts).
checked_at (optional)time (RFC 3339) or nullThe last check; ours: now (read from memory).
days_left (optional)number or nullWhole days left (UTC dates), counted to the earliest expiry in the chain; negative once expired.
error (optional)text or nullWhy the last check failed, if it did; ours: why renewed files can't be used (the pair loaded before is still presented).
fingerprint (optional)text or nullSHA-256 of the server certificate, hex.
hosttextOurs: this server's name.
issuer (optional)text or null
not_after (optional)time (RFC 3339) or nullThe server certificate's own expiry.
not_before (optional)time (RFC 3339) or null
portnumberOurs: 0 (see presented).
presentedlist of textOurs: where it is presented (0.0.0.0:6661 MLLP over TLS (adt), client certificate to hie.example.org:7443 (adt → hie)).
read_at (optional)time (RFC 3339) or nullWhen the certificate shown was read (older than checked_at when the last check couldn't).
resourcetextempi (resources.yaml), alerts.smtp, alerts.<channel>, alerts.heartbeat, or <interface>/<destination>; ours: the certificates: entry.
sidetextremote (a server the engine connects to, as its last check saw it) or ours (a pair the engine presents, as it loaded it).
stage (optional)number or nullThe step of the countdown it is within (a warn day; 0 once expired).
statetextok, expiring (within the first of alerts.certificates.warn_days), expired, or unknown (never read: not checked yet, or never reachable).
subject (optional)text or null
trusted (optional)true or false or nullThis server trusts it (none for ours: whether senders do isn't known here).

CertificatesOverview

FieldType
alertingtrue or falseA rule names certificate (alerts are sent about them).
certificateslist of CertificateInfoEarliest expiry first; never read ones last.
last_run (optional)DoctorRun or null
last_scheduled (optional)DoctorRun or null
modetextWhat those checks cover: certificates or full.
schedule_seconds (optional)number or nullHow often the engine checks by itself, in seconds; none when doctor.schedule: off.
warn_dayslist of numberThe steps of the countdown (alerts.certificates.warn_days).

Check

The result for one thing the project connects to.

FieldType
advicelist of textWhat a failure or warning most likely means, and what to do about it.
certificate (optional)SeenCertificate or null
endpointtextepic.local:5000 MLLP, a folder, 0.0.0.0:6661 MLLP.
outcomeOutcomeThe worst step.
stepslist of Step
used_bylist of text
whattextdatabase patient_db, api empi, destination adt → lab, listener.

DocsEntry

One documented thing and the values it has.

FieldType
custommap of name to any JSONValues by field key, as written in custom:.
interface (optional)text or nullThe interface it belongs to; none for a resource.
leveltextinterface, destination or resource.
missinglist of textRequired fields that have no value here.
nametextadt-lab, adt-lab.default, api empi.

DocsField

A field the company declared in docs-schema.yaml.

FieldType
applies_tolist of textinterface, destination, resource.
help (optional)text or null
keytext
requiredtrue or false
titletextThe label, else the key.
typetexttext, enum, date, url, person or list.
valueslist of textWhat an enum (or each item of a list) may be.

DocsReport

FieldType
entrieslist of DocsEntry
fieldslist of DocsFieldIn the order the file lists them.
problemslist of textWhat ductus validate would reject (wrong or undeclared values, missing required ones).

DoctorRequest

FieldType
interfaces (optional)list of textOnly what these interfaces use (the engine's database is always checked).
mode (optional)DoctorRunModefull (the default: logins included) or certificates (DNS, TCP and the TLS handshake of what has a certificate; nothing logs in).
timeout_ms (optional)number or nullLongest wait per step, in milliseconds (default 5000, at most 60000).

DoctorRun

FieldType
attime (RFC 3339)
checksnumber
failednumber
idnumber
modetextcertificates or full.
secondsnumber
started_bytextschedule, or who asked.

DoctorRunMode

full, certificates

ErrorBody

FieldType
errortextWhat went wrong, in plain words.

ImpactHit

FieldType
endpointslist of textHosts and ports, listening ports, folders to look at.
interfacetext
owner (optional)text or null
reasontextWhy it matched.
roletextsource, destination lab, database patient_db, api empi.

ImpactReport

FieldType
affectednumberInterfaces affected, of interfaces.
hitslist of ImpactHit
incompletelist of textInterfaces that don't name every system they connect (they may be missing here).
interfacesnumber
knownlist of textWith no hits for a vendor or application: the names that are known.
querytextWhat was looked for, e.g. vendor "Epic Systems".

ListeningPort

FieldType
allowtextWho may connect: the allow: list (10.1.20.0/24, epic-bridge01), or anyone.
allow_detail (optional)SourceAllow or null
hosttext
interfacetextThe interface, or (engine REST API).
portnumber
protocoltextMLLP, MLLP over TLS, HTTP or HTTPS.
route (optional)text or nullHTTP only: GET /patients/{mrn} (respond).
tlstextnone, or what it presents and asks for (presents ductus-mllp, clients need a certificate from hospital-ca).

OutboundPort

FieldType
hosttext
portnumber
protocoltextMLLP, MLLP over TLS, HTTP, HTTPS, SFTP, LDAP, LDAPS, Postgres, SQL Server, SQL Browser (UDP).
tlstextFor MLLP, HTTP and directories: none, TLS (the platform's trusted certificates), or TLS with what it trusts and presents (TLS: hie-ca trusted, client certificate ductus-client). Empty for SFTP (SSH) and databases.
used_bytextThe interface (adt → lab), or resources.yaml: <name>.

Outcome

ok, warn, fail

Owned

FieldType
destination (optional)text or nullSet for a destination owned by someone other than its interface's owner.
interfacetext

OwnedResource

FieldType
kindtextdatabase, api, sftp server or directory.
nametext

OwnerGroup

FieldType
advice (optional)text or nullHow the owner should be written instead, when it reaches someone but isn't written as their email (renamed, reused, a username or display name), in words.
owner (optional)text or nullAbsent for what nobody owns (listed last).
ownslist of OwnedInterfaces, and destinations owned by someone other than their interface's owner.
person (optional)OwnerPerson or null
reach (optional)text or nullWho the owner is: user (an account, in person), renamed (an account by a name it had before, which nobody has now: in person, the former name in was), reused (the account that has the name now, in person; another had it before, in was), disabled (an account that is disabled or refused by the directory, in person), several (names more than one account: none is chosen), team (in owners: in ductus.yaml), address (an email address, not an account) or nobody. Absent for the unowned. renamed and reused still reach person (alerts too); disabled, several and nobody reach no one.
resourceslist of OwnedResourceresources.yaml entries with this owner.
suggest (optional)text or nullWhat to write instead (the account's email), for the move's to.
was (optional)OwnerWas or null
youtrue or falseThe owner is the caller (or the person whose token calls).

OwnerPerson

An account, as an owner.

FieldType
disabledtrue or falseDisabled, or refused by the directory.
display_name (optional)text or null
email (optional)text or null
usernametext

OwnerWas

A name an account had before.

FieldType
kindtextusername, email or display_name.
untiltime (RFC 3339)When it stopped being theirs.
valuetext
whosetextThe account that had it (its username now).

PortsReport

FieldType
connects_tolist of OutboundPortWhat it connects to (destinations and resources.yaml), by host: what a firewall request lists.
listeninglist of ListeningPortWhat the engine listens on (its interfaces and the API), by port.

ReassignFile

FieldType
interface (optional)text or nullThe interface whose interface.yaml this is; absent for resources.yaml.
lineslist of ReassignLine
pathtextRelative to the project, /-separated.
resourceslist of textresources.yaml entries whose owner changes.

ReassignLine

FieldType
aftertext
beforetext
linenumber1-based.

ReassignPreview

FieldType
changednumberOwner values that would change, over all files.
commandtextThe same change made with the CLI in the project's folder.
fileslist of ReassignFileFiles that would change, each with its changed lines.
knownlist of textThe owners there are, when nothing matched from.
patchtextThe whole change as a unified diff, for git apply in the project's repository.
refusedlist of ReassignRefusedFiles with owner: <from> that can't be changed safely by a program (an unusual layout): change them by hand. While any is listed, patch and command are empty.
to_person (optional)OwnerPerson or null
to_reachtextThe new owner, as reach in /owners says it.
warning (optional)text or nullSaid when the new owner isn't an account (or names a disabled one, or several).

ReassignRefused

FieldType
errortext
interface (optional)text or nullAbsent for resources.yaml.
pathtext

ReassignRequest

FieldType
fromtextThe current owner (ignores case).
interfaces (optional)list of textOnly these interfaces. With neither interfaces nor resources, everything moves.
resources (optional)list of textOnly these resources.yaml entries (by name).
totextThe new owner.

Report

The whole report: what ductus doctor prints and --report saves.

FieldType
checkslist of Check
environmenttext
generated_attext
hosttext
notes (optional)list of textLines about this machine said before the checks (on Windows: the service's account).
secondsnumber
versiontext

SeenCertificate

A server's certificate as a check saw it.

FieldType
chain_earliest (optional)text or nullWhose that is, when it isn't the server certificate's (an intermediate).
chain_not_after (optional)time (RFC 3339) or nullThe earliest expiry in the chain the server presented.
error (optional)text or nullWhy the check failed: couldn't connect, not trusted, expired.
fingerprint (optional)text or nullSHA-256 of the server certificate (DER), hex.
hosttext
issuer (optional)text or null
not_after (optional)time (RFC 3339) or null
not_before (optional)time (RFC 3339) or null
portnumber
resourcetextWhat it belongs to: empi (resources.yaml), alerts.smtp, alerts.<channel>, alerts.heartbeat, <interface>/<destination>.
subject (optional)text or nullThe server certificate's common name (or organisation); none if none was read.
trustedtrue or falseThis server trusts it (the system's trusted certificates).

SourceAllow

A listener's allow: list and how it's doing.

FieldType
entrieslist of textThe list as written: addresses, subnets and host names.
last_refused (optional)text or nullThe last refused connection's address and time.
last_refused_at (optional)time (RFC 3339) or null
nameslist of AllowedNameEach host name in it with what it resolves to now.
refusednumberConnections refused since the engine started (0 when this engine doesn't hold the listener).

Step

One step of a check: DNS, connect, TLS, login, HTTP, commits, folder, port.

FieldType
detailtext
nametext
outcomeOutcome