diff --git a/.vale/styles/config/vocabularies/Smallstep/accept.txt b/.vale/styles/config/vocabularies/Smallstep/accept.txt index 77f561c7..ba10480e 100644 --- a/.vale/styles/config/vocabularies/Smallstep/accept.txt +++ b/.vale/styles/config/vocabularies/Smallstep/accept.txt @@ -952,3 +952,7 @@ publicKey serialNumber testuser disallow +nasIPs +autojoin +serverHostname +affordances diff --git a/learn/attestation-explained.mdx b/learn/attestation-explained.mdx new file mode 100644 index 00000000..28c3f1a2 --- /dev/null +++ b/learn/attestation-explained.mdx @@ -0,0 +1,107 @@ +--- +updated_at: September 13, 2026 +title: Attestation explained +html_title: Attestation explained +description: Assurance levels, secure elements, what a high-assurance device identity requires, and how key protection differs by platform. +kind: learn +--- + +Trust in a device's identity is a gradient, not a switch. +This page walks the gradient from identifiers nobody can rely on to keys a manufacturer vouches for, and says which level each platform can reach. + +## Assurance levels + +**No assurance.** +For decades devices were identified by a MAC address or an IP address. +Both are self-reported and both can be changed, so a policy built on them stands on nothing. + +**Low assurance.** +A user tells IT the serial number of their laptop. +The identifier is now permanent, immutable, and unique, which is an improvement, but the team has to take the user's word that it belongs to that laptop. + +**Inspected.** +An administrator reads the serial number off a company-purchased device before handing it out. +The inventory record is now trustworthy at the moment of inspection. +It says nothing about who is presenting that serial number over the network later. + +**High assurance.** +The device proves its identity cryptographically, using a secure element the manufacturer attested to. +Nothing in the operating system can forge the proof. +This is the level the platform calls *high assurance*, and the rest of this page is about how it is reached. + +## Secure elements + +A secure element is a cryptoprocessor, as a chip or as firmware, isolated from the main processor. +TPM 2.0 and Apple's Secure Enclave are the common examples. +It holds permanent identifiers and keys that can be proven to a third party, and it keeps working as designed even if the operating system around it is compromised. + +Each secure element carries a key pair created at manufacture. +The manufacturer signs a certificate for the public half. +That certificate is the root of every attestation the element will ever produce. + +## What a high-assurance identity requires + +Four proofs, together: + +1. **Proof of the device's identity**, from a platform certificate issued by the device maker (Lenovo, Dell, Apple). +2. **Proof of the secure element's identity**, from an endorsement key certificate issued by the element's maker (Infineon, STMicro, Apple). +3. **A binding between the two**, provided by the platform, so the verifier knows this element is inside this device. +4. **Proof that a private key is hardware-bound** on that element: usable by the device, never extractable without an exploit or destructive disassembly. + +Once these hold and a certificate is issued, a verifier can trust both the identity of the device and the residency of the key. +A side effect is zero-touch provisioning: +a new device can enroll itself on first boot with no credentials handed to it, because the hardware is the credential. + +## Which identifiers the platform attests + +- On Apple platforms, the device's serial number or hardware UDID, through Apple's Managed Device Attestation. +- On Windows, Linux, and ChromeOS devices with a TPM, the TPM endorsement key and, where present, the platform certificate. + +The protocol that carries the attestation to an authority is ACME with the `device-attest-01` challenge. +The device includes its attestation with the certificate order; the authority verifies the chain back to the manufacturer before it signs. +On the platform that authority is a dedicated attestation authority in your team, and the certificate it issues is what the agent then uses to obtain credentials for resources. + +## Key protection levels + +Getting a device identity is half the story. +The credentials a device then uses for Wi-Fi, SSH, or a browser each have a private key, and how well that key is protected varies by platform and application. + +| Level | What it means | What you are trusting | +|---|---|---| +| Software protected | The key is in memory or on disk (an SSH agent, an NSS database) | The OS, the application, and the user | +| Hardware bound | The key was generated in a secure element and cannot be exported; no proof of that exists | The local system's claim | +| Smallstep attested | The agent proves possession of a key it generated in the Secure Enclave to Smallstep's attestation authority; it cannot prove the key is inside a genuine Secure Enclave | System integrity protection, the agent, and the element | +| Hardware attested | The secure element itself produces a statement proving the key is hardware bound | The element's manufacturer | +| Device attested | The statement also proves which device or element holds the key, with a hardware identifier | The element's manufacturer | + +"Smallstep attested" exists because some applications on Apple platforms cannot use a device-attested key. +It is the weakest level the platform offers, used only where nothing stronger is available. + + +
+ Apple does not expose device attestation to user-space software, for privacy reasons. + Hardware attestation on Apple platforms is limited to the Managed Device Attestation workflow, which requires a supervised, MDM-managed device. +
+
+ +Because support is uneven, a credential can ask for hardware protection *with fallback*: +the agent uses the strongest level the environment supports. +For example, Apple platforms offer device-attested keys for Wi-Fi, while Windows has no native ACME device attestation, so a Windows Wi-Fi credential issued through the agent is hardware bound but attested by a different route. +The Devices list reports the assurance the device reached, not the level you asked for. + +## Bring-your-own devices + +A personal device used for work raises a privacy problem: +its permanent hardware identifiers should not be exposed to the employer. +Continuity is enough. +A cryptographically secure software identifier, scoped to your organization, can anchor policy and authentication for that device from then on. +What it cannot do is bootstrap trust: +the owner has to prove possession before the identity is trusted, because there is no manufacturer chain to lean on. + +## Where this shows up in Smallstep + +- The **Devices** list shows *high* or *normal* assurance per device. + [Inventory](../platform/concepts/inventory.mdx) describes the enrollment states around it. +- A credential's key protection (`HARDWARE_ATTESTED` or `HARDWARE_WITH_FALLBACK` in the API) picks the level; see [Credentials](../platform/concepts/credentials.mdx) and the credential step of the [Wi-Fi guide](../tutorials/protect-wireless-networks.mdx#create-the-credential). +- An MDM-managed Apple device can enroll with ACME device attestation and no agent; the [Wi-Fi guide](../tutorials/protect-wireless-networks.mdx#macos-with-jamf-pro-acme-device-attestation) shows it with Jamf Pro. +- [Why device identity](./why-device-identity.mdx) makes the case; [SCEP versus attestation](./scep-versus-attestation.mdx) compares this with the enrollment most MDMs still use. diff --git a/learn/certificates-for-people-devices-and-workloads.mdx b/learn/certificates-for-people-devices-and-workloads.mdx new file mode 100644 index 00000000..32ca8a27 --- /dev/null +++ b/learn/certificates-for-people-devices-and-workloads.mdx @@ -0,0 +1,87 @@ +--- +updated_at: September 13, 2026 +title: Certificates for people, devices, and workloads +html_title: Certificates for people, devices, and workloads +description: The three kinds of subject a certificate can name, what each one proves, how each is issued, and how they combine. +kind: learn +--- + +A certificate binds a key to a name. +Everything else depends on whose name it is. +The platform issues certificates to three kinds of subject, and each one is proven differently, lives a different length of time, and answers a different question at the verifier. + +## Devices + +A device certificate says: this is the laptop, phone, server, or instance we enrolled. +The proof is hardware. +The device attests, through its TPM or Secure Enclave, that the private key was generated inside it, and an authority signs only after verifying that attestation. +[Attestation explained](./attestation-explained.mdx) covers the mechanism. + +A device certificate is what a Wi-Fi network, a wired switch, a VPN, or a browser presents. +It is delivered and renewed by the Smallstep agent, or by an MDM profile where the agent is not present. +It carries the device's identity, usually its serial number and the email of the user bound to it, so a verifier can decide by device, by user, or by both. + +The question it answers: *is this a device we trust?* + +## People + +A user certificate says: this is the person who just signed in. +The proof is your identity provider. +The person authenticates with single sign-on; the identity provider returns an OpenID Connect token; the authority verifies the token and issues a certificate whose subject is the person's email. +No password is stored or shared anywhere in the exchange. + +User certificates are short-lived by design. +An SSH user certificate lasts 16 hours by default, so each workday starts with a fresh sign-in and access ends without anyone revoking anything. +X.509 user certificates for mutual TLS to APIs, databases, or a proxy follow the same shape. +Renewal is off for these on purpose: re-authenticating with the identity provider is the point. + +The question it answers: *is this the person they say they are, right now?* + +For SSH specifically, the certificate also carries the person's principals, the account names they may log in as, and, with the GitHub integration, their GitHub username. +[How SSH certificates work](../ssh/how-it-works.mdx) walks the login. + +## Workloads + +A workload certificate says: this is the nginx, the PostgreSQL, the `sshd`, the Kubernetes ingress running on that host. +The proof depends on where the workload runs. +On a host with the agent, the agent's device identity vouches for the workload it manages. +On a cloud instance, the instance identity document from AWS, GCP, or Azure does. +In Kubernetes, a service account token does. +For anything that speaks ACME, control of a DNS name does. + +A workload certificate is a server or client certificate for TLS between services. +It is renewed automatically, by the agent, by an ACME client, or by `step ca renew`, and it is usually short-lived because nobody has to type anything to renew it. + +The question it answers: *is this the service that should be on this connection?* + +## Side by side + +| | Device | Person | Workload | +|---|---|---|---| +| Proven by | Hardware attestation | Your identity provider | The host's identity, the cloud, Kubernetes, or DNS | +| Typical lifetime | Hours to days, renewed by the agent | Hours, renewed by signing in again | Hours to days, renewed automatically | +| Delivered by | Agent or MDM profile | `step ssh login` or the agent | Agent, ACME client, or `step` | +| Presented to | RADIUS, VPN, identity provider, web app | SSH host, API, proxy | Another service | +| Kind | X.509 | SSH or X.509 | X.509 or SSH host | + +## How they combine + +The strongest policy names both a person and a device. + +At sign-in, an identity provider can require a device certificate before it issues the person a session. +The session is then a bearer token, which the device certificate cannot follow, so the device is proven at login and the token is what reaches the app. +That is the pattern behind the SSO device factor. + +For SSH, an SSH user certificate can be issued through the agent on an enrolled device rather than through a browser login, so the certificate is bound to hardware as well as to a person. +Today the two are separate ways of getting an SSH user certificate; issuing one certificate with both proofs at once, the sign-in and the attestation, is planned and not yet available. + +For workloads, the host's device identity is what authorizes the workload's certificate, which is why a server enrolled with the agent can get its nginx certificate with nothing configured on the server but the agent. + +## Where this shows up in Smallstep + +- All three are **credentials**, defined by a template, an issuance method, and an assignment policy: [Credentials](../platform/concepts/credentials.mdx). +- Devices and the users bound to them are the [Inventory](../platform/concepts/inventory.mdx); a host is a device with a workload configured on it. +- Device certificates: the [Wi-Fi](../tutorials/protect-wireless-networks.mdx), [wired](../tutorials/protect-wired-networks.mdx), [VPN](../tutorials/vpn-setup-guide.mdx), and [web app](../tutorials/browser-certificate-setup-guide.mdx) guides. +- Person certificates: the [SSH client quickstart](../ssh/client.mdx) and [single sign-on certificates](../certificate-manager/oidc.mdx) for X.509. +- Workload certificates: [Kubernetes TLS](../certificate-manager/kubernetes-tls/README.mdx) and, for a cloud instance, [X.509 certificates for cloud VMs](../tutorials/cloud-vm-certificate.mdx). +- The open-source [provisioners](../step-ca/provisioners.mdx) page documents each issuance mechanism underneath. diff --git a/learn/how-smallstep-hosts-step-ca.mdx b/learn/how-smallstep-hosts-step-ca.mdx index 62653c44..39136da7 100644 --- a/learn/how-smallstep-hosts-step-ca.mdx +++ b/learn/how-smallstep-hosts-step-ca.mdx @@ -2,7 +2,89 @@ updated_at: September 13, 2026 title: How Smallstep hosts step-ca html_title: How Smallstep hosts step-ca -description: What a hosted authority shares with open-source step-ca, what the platform adds, and which page to read for each job. +description: What a hosted authority shares with open-source step-ca, what the platform adds around it, what is different, and which page to read for each job. +kind: boundary --- -A hosted authority is a step-ca. This page will say what is the same (provisioner types, which the platform calls issuance methods; templates; ACME; issuance policies; webhooks), what the platform adds (an inventory, hardware-attested issuance, credentials, verifiers, policy modes, audit), and which page to read for each job. Until it lands, the open-source [step-ca documentation](../step-ca/README.mdx) describes the shared mechanics. +A hosted Smallstep authority is a `step-ca`. +The open-source documentation on this site describes how that certificate authority works, and this documentation does not repeat it. +This page is the seam: +what is the same and documented once on the open-source side, what the platform builds around the authority, where the two differ, and which page to open for each job. + +## What is shared + +Everything below works the same way on a hosted authority as on a `step-ca` you run, and is documented on the open-source page linked. + +- **Provisioners**, the mechanisms by which a requester proves it may have a certificate. + The platform calls them *issuance methods* and shows the raw provisioner under Advanced and in the API. + The types and their options are on [Provisioners](../step-ca/provisioners.mdx). +- **Templates**, which set the fields and extensions of an issued certificate: [Templates](../step-ca/templates.mdx). +- **ACME**, including the `http-01`, `dns-01`, `tls-alpn-01`, and `device-attest-01` challenges: [ACME basics](../step-ca/acme-basics.mdx). +- **Issuance policies**, the allow and deny rules over the names an authority will sign: [Policies](../step-ca/policies.mdx). +- **Webhooks** called during signing to enrich or authorize a request: [Webhooks](../step-ca/webhooks.mdx). +- **Renewal** semantics, including renewal with the existing certificate and the daemon mode: [Renewal](../step-ca/renewal.mdx). +- **Revocation**, passive and active: [Revocation](../step-ca/revocation.mdx). +- **The `step` CLI**, which talks to any `step-ca`, hosted or self-run, and is used throughout the platform guides: [step CLI](../step-cli/README.mdx). + +## What the platform adds + +The authority is one piece. +Around it the platform runs the surfaces that [How Smallstep works](../start-here/how-smallstep-works.mdx) describes: + +- **An inventory** of devices and users, so a certificate is issued *to a device you enrolled* rather than to whoever presented a valid token. + [Inventory](../platform/concepts/inventory.mdx). +- **Hardware-attested issuance.** + Each team has an attestation authority that verifies TPM and Secure Enclave attestations, and the agent completes ACME `device-attest-01` against it on platforms without native support. + [Attestation explained](./attestation-explained.mdx). +- **Credentials** as the unit of configuration: a template, an issuance method, and an assignment policy that says which devices and users get the certificate. + You configure a credential; the platform configures the provisioner. + [Credentials](../platform/concepts/credentials.mdx). +- **Verifiers that Smallstep runs**, RADIUS for Wi-Fi and wired networks, the device factor for identity providers, relays, and the trust roots they need from your authorities. + [Verifiers](../platform/concepts/verifiers.mdx). +- **Delivery.** + The agent enrolls, renews, stores keys in hardware, and reloads services; MDM profiles do it for devices without the agent; the step-ssh package does it for SSH hosts. +- **Policy** beyond issuance: which devices get which credential, who may log in where, what happens when a device is quarantined. + [Policy](../platform/concepts/policy.mdx). +- **Audit**: events for every issuance and authentication, SSH sessions, webhooks to your systems. + [Audit](../platform/concepts/audit.mdx). + +## What is different + +Where an operator who knows `step-ca` will notice a divergence: + +- **Policy scope.** + A self-run `step-ca` takes an issuance policy at the authority level. + A hosted authority takes one at the authority, on each provisioner, and on each ACME account. +- **Administration.** + There is no `ca.json` to edit. + Provisioners, admins, and templates are managed in the Console and the API; `step ca provisioner` commands also work against a hosted authority after an admin sign-in. +- **Key custody.** + Signing keys are held in a cloud key management service and never leave it; an Advanced authority can be created with your own root, and the root's private key stays with you. + [Bring your own root](../certificate-manager/byo-root.mdx). +- **Renewal after expiry and active revocation** (CRL and OCSP) are options of an Advanced authority, enabled when it is created. +- **Linked authorities.** + A `step-ca` you run can be linked to the platform. + Its keys and signing stay on your infrastructure; the platform manages its provisioners and admins. + It is listed with your hosted authorities. +- **A registration authority** in front of a hosted authority is a platform object; the `step-ca` RA mode that fronts your own CA is documented at [Registration authority mode](../step-ca/registration-authority-ra-mode.mdx). + +## Which page? + +| I want to | Hosted authority | Self-run step-ca | +|---|---|---| +| Configure ACME for my servers | [ACME on a hosted authority](../certificate-manager/acme/README.mdx) | [ACME basics](../step-ca/acme-basics.mdx) | +| Write a certificate template | [Templates for credentials](../certificate-manager/custom-certs.mdx) | [Templates](../step-ca/templates.mdx) | +| Set an issuance policy | [Policies](../step-ca/policies.mdx), which covers both | same | +| Receive webhooks | [Webhook events](../certificate-manager/webhook-events.mdx) for platform events; [Webhooks](../step-ca/webhooks.mdx) for signing-time hooks | [Webhooks](../step-ca/webhooks.mdx) | +| Renew certificates | The agent, or [Issue certificates with your own clients](../certificate-manager/basic-ops.mdx) | [Renewal](../step-ca/renewal.mdx) | +| Revoke a certificate | [Issue certificates with your own clients](../certificate-manager/basic-ops.mdx) | [Revocation](../step-ca/revocation.mdx) | +| Run a registration authority | [Registration authorities](../registration-authorities/README.mdx) | [Registration authority mode](../step-ca/registration-authority-ra-mode.mdx) | +| Bring my own root | [Bring your own root](../certificate-manager/byo-root.mdx) | [Import an existing root or intermediate](../tutorials/intermediate-ca-new-ca.mdx) | +| Issue certificates to people with single sign-on | [Single sign-on certificates](../certificate-manager/oidc.mdx) | [OAuth/OIDC provisioner](../step-ca/provisioners.mdx#oauthoidc-single-sign-on) | +| Use `step` against my authority | [Issue certificates with your own clients](../certificate-manager/basic-ops.mdx) | [Basic certificate authority operations](../step-ca/basic-certificate-authority-operations.mdx) | + +## Running your own + +Run `step-ca` yourself when the signing keys must stay on hardware you own, when the authority must work without a connection to the internet, when you are building a lab, or when a certificate authority is all you need and an inventory, verifiers, and audit would be weight. +Everything you need is in the open-source section, starting at [step-ca](../step-ca/README.mdx). +If you later want the platform around it, link it as an authority and the rest of this documentation applies. diff --git a/learn/pki-in-one-page.mdx b/learn/pki-in-one-page.mdx new file mode 100644 index 00000000..4c62a3ab --- /dev/null +++ b/learn/pki-in-one-page.mdx @@ -0,0 +1,95 @@ +--- +updated_at: September 13, 2026 +title: PKI in one page +html_title: PKI in one page +description: Certificates, keys, authorities, chains, issuance, renewal, and revocation, in the order you meet them. +kind: learn +--- + +Public key infrastructure is the set of things that lets a stranger check a claim without a shared secret. +This page defines the seven words you will meet on every other page, in the order they depend on each other. +For the full treatment, read [Everything you should know about certificates and PKI](https://smallstep.com/blog/everything-pki/). + +## Keys + +Everything starts with a key pair. +The **private key** signs and decrypts; the **public key** verifies and encrypts. +Anyone may hold the public key. +Whoever holds the private key *is*, for every practical purpose, the identity. +That is why where the private key lives matters more than anything else on this page: +a key on disk can be copied, a key in a secure element cannot. +[Attestation explained](./attestation-explained.mdx) covers the levels. + +## Certificates + +A **certificate** is a signed statement that binds a public key to a name. +For X.509, the format used by TLS, the names are a subject and a list of subject alternative names: DNS names, IP addresses, email addresses, URIs. +For SSH, the names are principals. +A certificate also says what the key may be used for (server authentication, client authentication), when it becomes valid, and when it expires. + +A certificate proves nothing by itself. +It is a claim, and the signature on it is what makes the claim checkable. + +## Authorities + +A **certificate authority** is the party that signs certificates. +It holds a private key of its own and a certificate for the matching public key. +When a verifier trusts an authority, it accepts every certificate that authority signed, within the constraints the certificate carries. + +Authorities come in two roles. +A **root** signs only other authorities' certificates and is kept as far from the network as possible. +An **intermediate** is signed by the root and does the daily work of issuing certificates to devices, people, and workloads. +The indirection is what lets you rotate or retire an intermediate without touching every trust store. + +## Chains + +A verifier does not know your intermediate; it knows your root, because the root is what was installed in its trust store. +A presented certificate therefore has to arrive with the intermediate's certificate too, and the verifier walks the **chain**: +leaf signed by intermediate, intermediate signed by root, root in the trust store. +One missing link and the handshake fails with an error that looks like a bad certificate. +[Trust roots and chains](./trust-roots-and-chains.mdx) is about that failure and how to avoid it. + +## Issuance + +**Issuance** is how a requester proves to an authority that it is entitled to a certificate for a name. +The proof is the whole security of the system: sign for the wrong requester and the authority has minted an identity for an attacker. + +Methods differ by who the requester is. +A web server proves control of a DNS name (ACME). +A person proves who they are by signing in to the identity provider (OIDC). +A cloud instance presents its instance identity document. +A device presents a hardware attestation. +On a Smallstep authority these are *issuance methods*; the open-source `step-ca` calls them [provisioners](../step-ca/provisioners.mdx), and the mechanics are documented there. + +Issuance also decides what goes in the certificate. +A **template** sets the fields and extensions; an **issuance policy** sets what names an authority will and will not sign. + +## Renewal + +Certificates expire, on purpose. +A short lifetime bounds the damage from a key that leaks and keeps the fleet honest about which systems can still reach the authority. +**Renewal** replaces a certificate before it expires, authenticated by the certificate being renewed. +Automating it is the difference between a PKI that works and one that causes the outage everyone remembers. +On the platform, the agent renews device credentials; for anything else, `step ca renew` and ACME clients do it. + +## Revocation + +Sometimes a certificate must stop working before it expires: +the device was lost, the person left, the key leaked. +There are two ways. + +**Passive revocation** refuses to renew. +The certificate keeps working until it expires, so it depends on short lifetimes to be useful. +It is simple and it always works. + +**Active revocation** publishes a list (a CRL) or answers queries (OCSP) so verifiers can reject a certificate immediately. +It is what incident response wants, and it is only as good as the verifiers that check it. +Many do not, or cache the answer. +For systems that support it, revoking *authorization* (removing the device from the inventory, the user from the group) is often faster and more reliable than revoking the certificate. + +## Where this shows up in Smallstep + +- Your authorities, their roots and intermediates, and the certificates they have issued are under [Trust](../platform/concepts/trust.mdx). +- Templates, issuance methods, and lifetimes are set on a [credential](../platform/concepts/credentials.mdx). +- Renewal and revocation for device credentials are the agent's job; for certificates you issue with your own clients, see [Issue certificates with your own clients](../certificate-manager/basic-ops.mdx). +- The open-source [certificate authority core concepts](../step-ca/certificate-authority-core-concepts.mdx) page defines the same terms from the point of view of running `step-ca` yourself. diff --git a/learn/radsec.mdx b/learn/radsec.mdx new file mode 100644 index 00000000..11d83666 --- /dev/null +++ b/learn/radsec.mdx @@ -0,0 +1,74 @@ +--- +updated_at: September 13, 2026 +title: RadSec +html_title: RadSec (RADIUS over TLS) +description: What RADIUS over TLS is, why it exists, when you want it, and what the platform supports today. +kind: learn +--- + +RADIUS was designed for a network access server talking to an authentication server down the hall. +Today the access point is in your office and the RADIUS server is in a cloud region, and the protocol is carrying your fleet's Wi-Fi authentications across the internet. +RadSec is how you make that safe. + +## What RADIUS does in a certificate-based network + +In an 802.1X network, the access point or switch does not verify the device's certificate itself. +It relays the EAP-TLS handshake to a RADIUS server, which completes the TLS handshake with the device, checks the certificate against the trust roots it was given, and answers Access-Accept or Access-Reject. +The access point only opens the port when it hears Accept. + +The device's certificate and keys are protected by that inner TLS handshake. +Everything around it is plain RADIUS. + +## What plain RADIUS lacks + +Classic RADIUS runs over UDP and secures itself with a shared secret and MD5. +That was adequate on a LAN in 1997. +Over the internet it means: + +- **Attributes travel in the clear.** + The EAP payload is encrypted by TLS, but the RADIUS attributes around it, including the device's identity, the access point's identity, and any VLAN assignment coming back, are not. +- **A shared secret is the only authentication**, and it is shared by every access point that talks to the server. +- **The server identifies the client by source IP.** + A cloud RADIUS service has to know the public IP of every site that will send it traffic, and a change of ISP or a new office means updating that list before anyone can join the network. +- **UDP across the internet drops and reorders**, and RADIUS has no session to recover in; the client retries and the user waits. + +## What RadSec changes + +RadSec ([RFC 6614](https://datatracker.ietf.org/doc/html/rfc6614)) is RADIUS over TLS, on TCP port 2083. +The access point or controller opens a TLS connection to the RADIUS server, both sides present certificates, and every RADIUS packet flows inside that tunnel. + +- Attributes are encrypted end to end between the access point and the server. +- The server authenticates the access point by its certificate, not by its source IP, so sites can move and NAT can change without a registration step. +- The access point authenticates the server by its certificate, so an impostor RADIUS server cannot harvest handshakes. +- TCP gives ordered, reliable delivery and a long-lived connection instead of a fresh UDP exchange per authentication. + +The shared secret still exists in RadSec for protocol compatibility, but it is fixed and no longer carries the security. + +## When you want it + +RadSec is the right choice when the path between your access points and the RADIUS server crosses a network you do not control, which is every cloud-hosted RADIUS deployment. +It also removes the operational chore of keeping a list of public IPs current across offices and internet providers. + +The cost is that the access point or controller has to support it, has to be given the RADIUS server's CA so it can verify the server, and has to hold a client certificate the server will accept. +Not every access point does; most enterprise controllers do. +Check your vendor's documentation before planning on it. + +## What the platform supports today + +Smallstep RADIUS is offered in two forms, and the [Wi-Fi guide](../tutorials/protect-wireless-networks.mdx#step-2-configure-the-enforcement-point) documents both. + +- The multi-tenant service (**Managed RADIUS** in the guide) speaks RADIUS over UDP. + It attributes traffic to your team by the public IP addresses you register, which is the `nasIPs` list you set when you create the server. + You can create it yourself with the API. +- The dedicated deployment (**Enterprise RADIUS** in the guide) adds **RadSec transport with a dedicated hostname**, beside standard RADIUS over UDP, on infrastructure with static IPs in the regions you choose. + It also adds reply attributes for VLAN assignment and authorization webhooks. + Smallstep provisions it for your team; it is an add-on rather than something you create in the Console today. + +Both forms verify EAP-TLS only and check the full chain and revocation on every authentication. +The [wired guide](../tutorials/protect-wired-networks.mdx) uses the same servers for 802.1X on switches. + +## Where this shows up in Smallstep + +- The RADIUS server is the verifier for [Wi-Fi](../tutorials/protect-wireless-networks.mdx) and [wired](../tutorials/protect-wired-networks.mdx) networks; [Verifiers](../platform/concepts/verifiers.mdx) describes it beside the others. +- The trust roots the RADIUS server needs, and the server CA your devices need, are the subject of [Trust roots and chains](./trust-roots-and-chains.mdx). +- The per-vendor [access point reference](../tutorials/protect-wireless-networks.mdx#access-point-configuration-reference) shows where each vendor takes the RADIUS server settings. diff --git a/learn/scep-versus-attestation.mdx b/learn/scep-versus-attestation.mdx new file mode 100644 index 00000000..571d247e --- /dev/null +++ b/learn/scep-versus-attestation.mdx @@ -0,0 +1,89 @@ +--- +updated_at: September 13, 2026 +title: SCEP versus attestation +html_title: SCEP versus attestation +description: What SCEP proves and does not prove, why attestation closes the gap, and what SCEP is still the right tool for. +kind: learn +--- + +SCEP is how most MDM platforms get certificates onto devices, and it has done that job for two decades. +It also has a hole in the middle that attestation was designed to fill. +This page describes both honestly, because you will probably use both. + +## How SCEP enrollment works + +The Simple Certificate Enrollment Protocol ([RFC 8894](https://datatracker.ietf.org/doc/html/rfc8894)) is a request-and-response exchange between a device and a certificate authority. +In an MDM deployment: + +1. An employee enrolls their device with the MDM, usually by signing in. +2. The MDM sends the device a SCEP payload: a server URL, the fields the certificate should carry, and a challenge password. +3. The device generates a key pair and sends a signing request with the challenge to the SCEP server. +4. The server checks the challenge and returns a signed certificate. + +The device now has a certificate it can use for Wi-Fi, VPN, or anything else the MDM configured. + +## What SCEP does not prove + +Look at step 3. +The device sends a signing request and a password. +Nothing in the exchange is evidence about the device itself. +The authority cannot tell whether the request came from the laptop the MDM enrolled, from a virtual machine, or from a script on an attacker's desk that happens to hold the payload. +There is no known identity for the device at the moment it first identifies itself. + +The challenge password is the whole gate, and passwords travel. +If a phishing page captures the user's MDM sign-in, the attacker can enroll a device the organization never approved. +If a configuration profile leaks, anyone who reads it can request a certificate and impersonate the user it was meant for. +The private key, meanwhile, was generated by software and may sit on disk, where it can be copied. + +SCEP comes in two flavors and only one is acceptable: + +- **Static SCEP** puts the same challenge password in every payload for every device. + One leak compromises the whole fleet, and every device looks like one user in reporting. + Smallstep does not support it. +- **Dynamic SCEP** uses a webhook to mint a unique challenge per device, so each enrollment is distinct and reportable. + Jamf Pro, Intune, Workspace ONE, Mosyle, Ivanti, and Google Workspace support it, and this is what the platform integrates with. + +Dynamic SCEP fixes the shared-secret problem. +It does not fix the evidence problem. + +## What attestation adds + +With attestation, the device does not merely present a password; it presents a signed statement from its secure element, chained to the manufacturer, that says which device this is and that the private key was generated inside that hardware. +The authority verifies the statement before signing. +The gate is now "is this hardware one we enrolled", which a phishing page cannot satisfy and a leaked profile cannot replay. + +The standard form is ACME with the `device-attest-01` challenge. +Apple and ChromeOS support it natively for managed devices; on Windows and Linux the Smallstep agent performs the attestation with the TPM. +[Attestation explained](./attestation-explained.mdx) describes the levels in detail. + +| | Dynamic SCEP | ACME device attestation | +|---|---|---| +| What gates issuance | A per-device challenge password | A manufacturer-signed statement about the hardware | +| Where the key lives | Software, unless the MDM and OS bind it to hardware | The secure element; not exportable | +| Survives a phished MDM login | No | Yes | +| Survives a leaked profile | No | Yes | +| Ties the certificate to an inventory record | By what the MDM says | By what the hardware proves | +| Needs an agent | No | Only on platforms without native support | + +## What SCEP is still good for + +SCEP is not going away, and on the platform it has two honest jobs. + +**Devices that cannot attest through the platform.** +Most MDMs have not adopted ACME device attestation, and some platforms cannot run the agent. +For an MDM-managed device without the agent, a dynamic SCEP certificate issued by your hosted authority is still a large improvement over a shared password on the Wi-Fi, and the device appears in your inventory with *normal* assurance rather than *high*. +The [Wi-Fi guide](../tutorials/protect-wireless-networks.mdx#mdm-managed-clients) shows this with Jamf Pro and Intune. + +**Bootstrapping the agent.** +The agent needs a provisional identity to open its first authenticated channel to the platform. +A SCEP certificate delivered by the MDM is a good one: it proves the device is in the MDM's inventory, which is enough to begin the attestation that produces the real, hardware-bound identity. +After that, the SCEP certificate has done its job. + +SCEP is also how the platform stands in for Active Directory Certificate Services during a migration, since it speaks SCEP and NDES to the workloads that still expect them. + +## Where this shows up in Smallstep + +- SCEP is configured when you connect an MDM; see [Jamf Pro](../tutorials/connect-jamf-pro-to-smallstep.mdx), [Intune](../tutorials/connect-intune-to-smallstep.mdx), [Mosyle](../tutorials/connect-mosyle-to-smallstep.mdx), and [Workspace ONE](../tutorials/connect-workspace-one-to-smallstep.mdx). +- The **Devices** list shows *normal* assurance for a SCEP-only device and *high* for one that attested; [Inventory](../platform/concepts/inventory.mdx) explains. +- A credential's issuance method is where the choice lives; see [Credentials](../platform/concepts/credentials.mdx). +- The open-source [SCEP provisioner](../step-ca/provisioners.mdx#scep) is the mechanism underneath a hosted authority's SCEP support. diff --git a/learn/trust-roots-and-chains.mdx b/learn/trust-roots-and-chains.mdx new file mode 100644 index 00000000..430a04a2 --- /dev/null +++ b/learn/trust-roots-and-chains.mdx @@ -0,0 +1,93 @@ +--- +updated_at: September 13, 2026 +title: Trust roots and chains +html_title: Trust roots and chains +description: Why a verifier needs the whole chain, what roots and intermediates each do, and what "trust roots" means on the platform. +kind: learn +--- + +The most common reason a certificate-based setup fails on the first try is not the certificate. +It is that the thing checking the certificate was never told whom to trust, or was told half of it. +This page is about that half. + +## A verifier only knows what it was given + +When a device presents a certificate, the verifier, whether a RADIUS server, an identity provider, an SSH daemon, or a web server, has one question: +was this signed by an authority I trust? +It answers by looking in its own trust store. +Whatever is in that store is the whole universe of authorities the verifier will accept. +A certificate from anyone else is rejected with an error that usually blames the certificate. + +Every use case therefore has a step that is easy to skip: +put your authority's trust roots where the verifier will look. +The [Wi-Fi guide](../tutorials/protect-wireless-networks.mdx) does it when it registers your client CA with the RADIUS server; the [SSH guide](../ssh/hosts.mdx) does it when it points `sshd` at the user CA; a web app does it in its server configuration. + +## Roots and intermediates + +An authority is usually two certificates, not one. + +The **root** is self-signed and long-lived. +Its private key signs only the intermediate's certificate and is otherwise kept out of reach. +The root is what goes into trust stores, because it changes rarely. + +The **intermediate** is signed by the root and does the daily signing of device, user, and workload certificates. +It can be rotated, replaced, or revoked without touching a single trust store, as long as the new one is signed by the same root. + +A hosted Smallstep authority is built this way, and so is a [`step-ca`](../step-ca/certificate-authority-core-concepts.mdx) you run yourself. +Bringing your own root keeps the same shape: +your existing root signs a Smallstep intermediate, and everything that already trusts your root trusts what the intermediate issues. + +## The chain + +A verifier that trusts the root has never seen the intermediate. +The presenter must therefore send both its own certificate and the intermediate's certificate, and the verifier walks the chain: + +```mermaid +flowchart LR + leaf["Device certificate
(sent by the device)"] -->|signed by| intermediate["Intermediate
(sent by the device)"] -->|signed by| root["Root
(in the verifier's trust store)"] +``` + +Three ways this breaks, and they all look the same from the outside: + +- The device sends only its own certificate, and the verifier cannot get from it to the root. +- The verifier's trust store holds the intermediate but not the root, or a root that has since been rotated. +- The verifier holds the right root but the certificate was issued by a different authority than the one whose root was installed. + +Where the chain is supplied depends on the verifier. +A RADIUS server is usually given the full bundle, root and intermediate, because EAP-TLS clients do not always send intermediates. +A web server is given the root and relies on the client to send its intermediate. +The guide for each use case says which. + +## Trust goes both ways + +Most conversations about trust roots are about the verifier trusting the device. +In the Wi-Fi case the device also has to trust the RADIUS server, or it will refuse to hand over its certificate to an impostor access point. +That is a second trust root, the RADIUS server's CA, delivered to the device in the network profile. +The two are independent: your client CA on the server, the server's CA on the client. +The [Wi-Fi guide](../tutorials/protect-wireless-networks.mdx#step-3-configure-clients) sets both. + +## What "trust roots" means on the platform + +On the platform, *trust roots* are the anchors of an authority as a verifier needs them: the root, usually with the intermediate, as a PEM bundle. +Every authority publishes its bundle on its page under **Authorities**, and at a fixed URL on the authority's domain, `https:///roots.pem`, so you can fetch it in automation. + +Where those bundles go today: + +| Verifier | Where the trust roots go | Guide | +|---|---|---| +| Smallstep RADIUS | The `clientCA` of the RADIUS server | [Wi-Fi](../tutorials/protect-wireless-networks.mdx#option-1-smallstep-managed-radius) | +| Your own RADIUS server | Its trusted client CA bundle | [Wi-Fi](../tutorials/protect-wireless-networks.mdx#option-3-bring-your-own-radius-server) | +| The device, for the RADIUS server | `radiusServerCA` on the Wi-Fi resource | [Wi-Fi](../tutorials/protect-wireless-networks.mdx#step-3-configure-clients) | +| A relay | The relay's trust bundle | [Relays](../tutorials/configure-enterprise-relay.mdx) | +| A web server or SaaS app | Its client CA configuration | [Web apps](../tutorials/browser-certificate-setup-guide.mdx) | +| An SSH host | `TrustedUserCAKeys` in `sshd_config` | [SSH hosts](../ssh/hosts.mdx) | + +That the roots are copied into several places by hand is a known cost, and the reason a rotation has to be planned. +A Trust view that records which verifier relies on which authority, and verifies it, is planned; it is not available today. + +## Where this shows up in Smallstep + +- Download an authority's trust roots from its page under [Trust](../platform/concepts/trust.mdx). +- [Bring your own root](../certificate-manager/byo-root.mdx) explains the root-signs-intermediate arrangement when the root is yours. +- Every use-case guide has the step where trust roots are placed; the [Wi-Fi](../tutorials/protect-wireless-networks.mdx) and [wired](../tutorials/protect-wired-networks.mdx) guides are the clearest examples. +- [PKI in one page](./pki-in-one-page.mdx) defines the words; the open-source [`step ca root`](../step-cli/reference/ca/root/README.mdx) and [`step certificate install`](../step-cli/reference/certificate/install/README.mdx) commands fetch and install a root from any `step-ca`, hosted or not. diff --git a/learn/why-device-identity.mdx b/learn/why-device-identity.mdx new file mode 100644 index 00000000..ea760ad4 --- /dev/null +++ b/learn/why-device-identity.mdx @@ -0,0 +1,79 @@ +--- +updated_at: September 13, 2026 +title: Why device identity +html_title: Why device identity +description: Why a credential that can be copied proves nothing about a device, and what changes when identity is attested by hardware. +kind: learn +--- + +Most access control answers one question: is this the right person? +Passwords, one-time codes, and passkeys all answer it. +None of them answers the second question that matters just as much: +is this person on a device we trust? +Device identity is how you answer the second question with the same rigor as the first. + +## Identity that can move is not identity + +Many products offer something they call device identity. +Look closely and it is usually one of two things. +Either the device reports an identifier about itself, such as a serial number, a MAC address, or a hostname, and the system takes its word for it. +Or the device holds a credential, a certificate or a token, that was placed there during setup. + +Both fall apart under the same question: can it be moved? +A self-reported identifier can be typed by anyone. +A credential stored on disk, or in a keychain that will export it, can be copied to another machine, and that machine becomes "the device" as far as every system is concerned. +Phishing does not need to steal a password if it can steal the thing that stands in for the device. + +Think of a passport. +A person does not prove citizenship by stating their name; they present a document that their government attested to and signed, tied to them by a photo and biometrics. +A device should have to present the same kind of evidence: a statement about itself that it could not have forged, signed by a party the verifier already trusts. + +## What attestation changes + +Modern devices ship with a secure element: +a TPM 2.0 on Windows and Linux machines, the Secure Enclave on Apple hardware, a comparable chip on ChromeOS. +It is isolated from the main processor and the operating system. +It can generate a private key that never leaves it, and it can sign a statement, backed by a key the manufacturer burned in at the factory, that says "this key lives inside me, on this device". + +That statement is an attestation. +An authority that receives one can check the manufacturer's signature, confirm the device is one it expects, and then issue a certificate whose private key is provably bound to that hardware. +The certificate cannot be copied in any useful way, because the key it belongs to cannot be exported. +Presenting it proves not just "someone has this certificate" but "this device, the one we enrolled, is the one connecting now". + +The standard that carries this between the device and the authority is ACME with the `device-attest-01` challenge. +The device sends the attestation with its certificate request; the authority verifies it before signing. +Apple ships it natively for managed devices; Smallstep co-developed the standard and performs the attestation through the agent on devices with a TPM. +[Attestation explained](./attestation-explained.mdx) walks through the levels of assurance and what each one requires. + +## What that buys you + +**Only enrolled devices get credentials.** +An attacker with a stolen password, a stolen configuration profile, or a stolen SCEP challenge cannot enroll a device you have not approved, because the authority will not sign for hardware it does not recognize. +[SCEP versus attestation](./scep-versus-attestation.mdx) explains the gap in the protocol most MDMs still use. + +**Credentials cannot be exfiltrated.** +A hardware-bound key can be used on the device to sign or decrypt, and that is all. +Malware that reads the disk gets nothing it can reuse elsewhere. + +**Access decisions can name the device.** +Because the certificate is tied to an inventory record, a Wi-Fi network, an identity provider, an SSH host, or a web app can decide based on which device is asking, not just who claims to be typing. +When a laptop is lost or an employee leaves, revoking that device's certificates ends its access everywhere at once. + +**Nobody types anything.** +The device proves itself during the handshake. +Users stop entering Wi-Fi passwords, stop juggling VPN certificates, stop being the weak point of an enrollment flow. + +## What it does not replace + +Device identity is not a substitute for user identity. +The strongest posture requires both: this user, on this device. +On the platform they combine, for example when an identity provider requires a device certificate at sign-in and then issues the user a session, or when an SSH certificate carries both the user's principal and the device it was issued to. +[Certificates for people, devices, and workloads](./certificates-for-people-devices-and-workloads.mdx) describes the three kinds and how they combine. + +## Where this shows up in Smallstep + +- The **Devices** list shows each device's assurance level; high assurance means the device attested. + [Inventory](../platform/concepts/inventory.mdx) explains the states. +- A **credential** asks for a hardware-attested key by default; [Credentials](../platform/concepts/credentials.mdx) explains the choices. +- Every use-case guide starts from this argument: [Wi-Fi](../tutorials/protect-wireless-networks.mdx), [wired networks](../tutorials/protect-wired-networks.mdx), [VPN](../tutorials/vpn-setup-guide.mdx), and [web apps](../tutorials/browser-certificate-setup-guide.mdx). +- [How Smallstep works](../start-here/how-smallstep-works.mdx) shows where the attested identity enters the loop. diff --git a/manifest.json b/manifest.json index e7bdb94e..9971be42 100644 --- a/manifest.json +++ b/manifest.json @@ -13,29 +13,60 @@ }, { "title": "How Smallstep works", - "path": "/platform/README.mdx" + "path": "/start-here/how-smallstep-works.mdx" }, { "title": "Quickstart", - "path": "/start-here/quickstart.mdx", - "hideFromSidebar": true + "path": "/start-here/quickstart.mdx" }, { "title": "For coding agents", - "path": "/start-here/for-coding-agents.mdx", + "path": "/start-here/for-coding-agents.mdx" + }, + { + "title": "What is Smallstep?", + "path": "/platform/README.mdx", "hideFromSidebar": true }, { "heading": true, "title": "Learn" }, + { + "title": "Why device identity", + "path": "/learn/why-device-identity.mdx" + }, { "title": "Attestation explained", - "path": "/platform/core-concepts.mdx" + "path": "/learn/attestation-explained.mdx" + }, + { + "title": "SCEP versus attestation", + "path": "/learn/scep-versus-attestation.mdx" + }, + { + "title": "PKI in one page", + "path": "/learn/pki-in-one-page.mdx" + }, + { + "title": "Trust roots and chains", + "path": "/learn/trust-roots-and-chains.mdx" + }, + { + "title": "RadSec", + "path": "/learn/radsec.mdx" + }, + { + "title": "Certificates for people, devices, and workloads", + "path": "/learn/certificates-for-people-devices-and-workloads.mdx" }, { "title": "How Smallstep hosts step-ca", - "path": "/learn/how-smallstep-hosts-step-ca.mdx", + "path": "/learn/how-smallstep-hosts-step-ca.mdx" + }, + { + "title": "Core concepts", + "path": "/platform/core-concepts.mdx", "hideFromSidebar": true }, { @@ -179,13 +210,45 @@ "heading": true, "title": "Concepts" }, + { + "title": "Concepts", + "path": "/platform/concepts/README.mdx", + "routes": [ + { + "title": "Inventory", + "path": "/platform/concepts/inventory.mdx" + }, + { + "title": "Trust", + "path": "/platform/concepts/trust.mdx" + }, + { + "title": "Credentials", + "path": "/platform/concepts/credentials.mdx" + }, + { + "title": "Verifiers", + "path": "/platform/concepts/verifiers.mdx" + }, + { + "title": "Policy", + "path": "/platform/concepts/policy.mdx" + }, + { + "title": "Audit", + "path": "/platform/concepts/audit.mdx" + } + ] + }, { "title": "Trust (Certificate Manager core concepts)", - "path": "/certificate-manager/core-concepts.mdx" + "path": "/certificate-manager/core-concepts.mdx", + "hideFromSidebar": true }, { "title": "Trust (Certificate Manager how it works)", - "path": "/certificate-manager/how-it-works.mdx" + "path": "/certificate-manager/how-it-works.mdx", + "hideFromSidebar": true }, { "heading": true, diff --git a/platform/concepts/README.mdx b/platform/concepts/README.mdx new file mode 100644 index 00000000..9cfda2fb --- /dev/null +++ b/platform/concepts/README.mdx @@ -0,0 +1,56 @@ +--- +updated_at: September 13, 2026 +title: Concepts +html_title: Platform concepts +description: "One page per surface of the platform: what it is, how it relates to the others, and where it appears in the Console and the API." +kind: concept +--- + +Six words carry the platform. +Each page below says what the word means, how it relates to the others, and where you meet it in the Console and the API. +[How Smallstep works](../../start-here/how-smallstep-works.mdx) shows the six together in one loop; the [Learn](../../learn/why-device-identity.mdx) section explains why they are shaped this way. + +
+ + + + + + +
diff --git a/platform/concepts/audit.mdx b/platform/concepts/audit.mdx new file mode 100644 index 00000000..de12a588 --- /dev/null +++ b/platform/concepts/audit.mdx @@ -0,0 +1,59 @@ +--- +updated_at: September 13, 2026 +title: Audit +html_title: Audit +description: "What happened: events with a time and a subject, sessions with a timeline, and the exports built from them." +kind: concept +--- + +Audit is the team's record of what happened: +every certificate issued, every authentication accepted or rejected, every device enrolled or approved, every SSH session. +Every object page shows the slice about itself; the Audit tab shows all of it with one set of filters. +Records are append-only. + +## The record kinds + +**Event.** +One thing that happened, with a time, a category, a type, and a subject: a certificate was issued, RADIUS answered Access-Accept, a device registered, an MDM sync completed. +Events are what you filter and search. + +**Session.** +A bounded interaction with a timeline. +An SSH session records the login, `su` and `sudo` changes, and the logout on a host, with a terminal recording where enabled. + +**Export.** +A copy of selected records pushed to your own systems. +Webhooks today: certificate requests, certificate expirations, and SSH session events, delivered as JSON to an endpoint you register. + +## How it relates + +```mermaid +flowchart LR + authority["Authority
issues, renews, revokes"] --> log["Audit"] + log -->|activity panel| page["Each object page"] + log -->|webhook| external["Your SIEM or endpoint"] + verifier["Verifier
accepts, rejects"] --> log + inventory["Inventory
enrolls, approves"] --> log + host["SSH host
login, sudo, logout"] --> log +``` + +Audit records; it does not interpret. +Whether a fleet is healthy is a question for the resource and device pages, computed from these records and the inventory. + +## Where it appears + +- **Console**: the **Audit** tab lists the team's events with filters by time, type, and subject. + A device's page shows its own events; a Wi-Fi resource shows its authentication activity; SSH sessions are listed under the SSH configuration (the **SSH Pro** menu today), with a per-session timeline. +- **Webhooks**: registered under **Settings › Webhooks** and documented on [Webhook events](../../certificate-manager/webhook-events.mdx). +- **API**: certificate lifecycle is visible through [`/certificates`](https://gateway.smallstep.com/v2025-01-01/operations/ListCertificates); SSH session webhooks carry the session ID. + See [Smallstep API](../smallstep-api.mdx). + +A single Sessions view for SSH and other session kinds, policy decisions as records, and a SIEM export in a standard schema are planned and not available today. + +## Guides that use it + +- The [Wi-Fi guide](../../tutorials/protect-wireless-networks.mdx#verify-and-troubleshoot) verifies a deployment by watching the resource's authentication activity. +- [Webhook events](../../certificate-manager/webhook-events.mdx) for exports. +- [How SSH works](../../ssh/how-it-works.mdx) for how session events are produced on a host. +- [Agent troubleshooting](../troubleshooting-agent.mdx) starts from a device's events. +- Related concepts: every other surface emits into Audit; [Policy](./policy.mdx) decisions will be recorded here once policy modes ship. diff --git a/platform/concepts/credentials.mdx b/platform/concepts/credentials.mdx new file mode 100644 index 00000000..3dc645fe --- /dev/null +++ b/platform/concepts/credentials.mdx @@ -0,0 +1,73 @@ +--- +updated_at: September 13, 2026 +title: Credentials +html_title: Credentials +description: The certificate a device, user, or host gets, defined by a certificate template, an issuance method, and an assignment policy. +kind: concept +--- + +A credential is the certificate a device, user, or host gets so that it can reach a resource. +It is a configuration, not an issued certificate: +one credential produces many certificates, one per device or user it is assigned to, and renews them for as long as the assignment holds. + +## Three parts + +**A certificate template.** +Which authority signs, the certificate's lifetime, what goes in the subject and the subject alternative names (the device's serial, hostname, or permanent identifier; the bound user's email; static values), and the key usages. +The open-source [Templates](../../step-ca/templates.mdx) page documents the template language; on a credential the common fields are filled from device and user metadata. + +**An issuance method.** +How the certificate is obtained and how strongly its key is protected: + +- *Hardware-attested*: the key is generated in the device's TPM or Secure Enclave and the authority requires an attestation before signing. +- *Hardware with fallback*: hardware where available, a software key elsewhere. +- *SCEP*: issued through the MDM's SCEP flow, for devices without the agent. +- *Single sign-on*: the person authenticates with your identity provider and the certificate carries their identity. + +[Attestation explained](../../learn/attestation-explained.mdx) explains what each level proves. + +**An assignment policy.** +Which devices and users get the credential: +by assurance, ownership, operating system, source, and tags, and optionally only devices with a bound user. +An empty policy selects every device. +[Policy](./policy.mdx) describes it beside the other policy kinds. + +## Two kinds + +An **X.509 credential** is presented to Wi-Fi, wired networks, VPNs, identity providers, web apps, relays, and services. +An **SSH credential** is an SSH user certificate (for people logging in) or an SSH host certificate (for the host they log in to). + +## Delivery + +A credential is inert until something puts the certificate on the device and keeps it current: + +- **The agent** enrolls, generates the key in hardware, requests and renews the certificate, and configures the resource (the Wi-Fi profile, the browser, the VPN, the service reload). +- **An MDM profile** delivers a certificate and a network or VPN profile to a device without the agent; the MDM's SCEP or ACME flow renews it. +- **The step-ssh host package** delivers the host certificate and access rules to an SSH host. +- **Manual**: `step ssh login` for an SSH user certificate, or a downloaded profile. + +The API field for this choice is `managementMode`: `agent`, `mdm`, or `other` when some other process handles enrollment and renewal. + +## How it relates + +```mermaid +flowchart LR + authority["Authority"] -->|signs under| credential["Credential
template + issuance method + assignment policy"] + credential -->|selects| devices["Devices and users
(Inventory)"] -->|delivered by agent or MDM| cert["Certificate on the device"] -->|presented to| verifier["Verifier"] + credential -->|used by| resource["Resource
(Wi-Fi, VPN, app, SSH hosts)"] +``` + +## Where it appears + +- **Console**: credentials have their own list, labelled **Endpoints** under the **Certificate Manager** menu today; a resource under **Protect** references the credentials its clients authenticate with. +- **API**: [`/credentials`](https://gateway.smallstep.com/v2025-01-01/operations/PostCredentials) in the 2025-01-01 version; a resource such as `/protect/wifi` lists the credential IDs it uses. + The older `/endpoint-configurations` and `/accounts` paths are deprecated. + See [Smallstep API](../smallstep-api.mdx). + +## Guides that use it + +- The [Wi-Fi guide](../../tutorials/protect-wireless-networks.mdx#step-1-configure-credential-issuance) creates a credential and explains every field; the [Quickstart](../../start-here/quickstart.mdx) does it in one call. +- [Wired networks](../../tutorials/protect-wired-networks.mdx), [VPN](../../tutorials/vpn-setup-guide.mdx), and [web apps](../../tutorials/browser-certificate-setup-guide.mdx) reuse the same object. +- [Templates](../../certificate-manager/custom-certs.mdx) for lifetimes and custom fields. +- SSH user credentials: the [SSH client quickstart](../../ssh/client.mdx); SSH host credentials: the [host quickstart](../../ssh/hosts.mdx). +- Related concepts: [Trust](./trust.mdx) for the authority; [Inventory](./inventory.mdx) for what is selected; [Verifiers](./verifiers.mdx) for what checks the result. diff --git a/platform/concepts/inventory.mdx b/platform/concepts/inventory.mdx new file mode 100644 index 00000000..c8304492 --- /dev/null +++ b/platform/concepts/inventory.mdx @@ -0,0 +1,75 @@ +--- +updated_at: September 13, 2026 +title: Inventory +html_title: Inventory +description: "What the team has: devices, the users bound to them, how each device got in, and how strongly its identity was proven." +kind: concept +--- + +Inventory is the set of devices your team knows about that can hold a credential, plus the users bound to them. +Every credential is issued to something in the inventory, every access decision is about something in the inventory, and every audit record names something in it. +Nothing outside the inventory gets a certificate. + +## What is in it + +**Devices.** +A laptop, a phone, a server, a VM, a cloud instance. +There is no separate category for servers; a host is a device that runs a workload. +Each device record carries: + +- **Identity**: the identifier the platform matched it on, in order of preference a host ID reported by the agent, a permanent identifier from the MDM or an attestation, or a serial number. +- **Source**: where it came from (the agent, an MDM sync, the API). +- **Assurance**: *high* if the device attested through its secure element, *normal* otherwise. [Attestation explained](../../learn/attestation-explained.mdx) defines the levels. +- **Enrollment state**: whether the device has been approved for credentials. +- **Ownership** (company or user), operating system, tags, and metadata you set. +- **Certificates** issued to it and the agent's status, if it runs the agent. +- **Users** bound to it, with one primary. + +**Users.** +People from your directory, synced from Okta, Google Workspace, or Entra ID, with their groups. +A user bound to a device is what lets a credential carry the person's email as well as the device's serial. + +## How a device gets in + +```mermaid +flowchart LR + inventory["Inventory"] -->|approve| approved["Approved"] -->|attestation| high["High assurance"] + mdm["MDM sync
(Jamf, Intune, and others)"] --> inventory + agent["Agent self-registration
(invite or SSO)"] --> inventory + api["API import"] --> inventory +``` + +Four routes, and a device can arrive by more than one; records from different sources are linked into one device. + +| Route | Approved automatically | High assurance | +|---|---|---| +| A user installs the agent and registers, by invitation or by single sign-on | No, an admin approves, unless you change the team setting | Once the agent attests | +| An MDM sync imports the MDM's inventory | No | Once the agent, or an ACME device attestation profile, attests | +| An import through the API | Yes | Once the agent attests | + +The details are in [Build your inventory](../enrollment-guide.mdx) and the per-MDM pages under Inventory › Enrollment. + +## Tags organize; what is configured discriminates + +Tags are yours. +You decide the axes (`env:prod`, `role:bastion`, `team:payments`), and a credential's assignment policy selects devices by them, together with assurance, ownership, operating system, and source. +The platform reserves no tag and never infers a category from one. + +What a device *does* is visible in what is configured on it: +a Wi-Fi network, a browser certificate, a VPN, a workload. +A laptop and a server are the same kind of record; they differ in what their credentials configured. + +## Where it appears + +- **Console**: the **Devices** tab is the one list, with a detail page per device showing identity, status, certificates, and activity. + The **Users** tab lists directory users and their device bindings. + MDM connections and the enrollment policy are under **Settings**. +- **API**: [`/devices`](https://gateway.smallstep.com/v2025-01-01/operations/ListDevices) to list, import, and update devices; `/platforms` for MDM connections; `/device-enrollment-policy` for the approval rules. + See [Smallstep API](../smallstep-api.mdx). + +## Guides that use it + +- [Build your inventory](../enrollment-guide.mdx), then connect an MDM: [Jamf Pro](../../tutorials/connect-jamf-pro-to-smallstep.mdx), [Intune](../../tutorials/connect-intune-to-smallstep.mdx), [Mosyle](../../tutorials/connect-mosyle-to-smallstep.mdx), [Workspace ONE](../../tutorials/connect-workspace-one-to-smallstep.mdx), [JumpCloud](../../tutorials/connect-jumpcloud-to-smallstep.mdx), [Fleet](../../tutorials/connect-fleet-dm-to-smallstep.mdx), [Google Workspace](../../tutorials/connect-google-workspace-to-smallstep.mdx). +- Sync users from [Okta](../../tutorials/sync-okta-users-to-smallstep.mdx), [Google Workspace](../../tutorials/sync-google-workspace-users-to-smallstep.mdx), or [Entra ID](../../tutorials/sync-entra-id-users-to-smallstep.mdx). +- [Install the agent](../smallstep-agent.mdx). +- Related concepts: [Credentials](./credentials.mdx) are issued to inventory items; [Policy](./policy.mdx) selects them. diff --git a/platform/concepts/policy.mdx b/platform/concepts/policy.mdx new file mode 100644 index 00000000..6c977ca9 --- /dev/null +++ b/platform/concepts/policy.mdx @@ -0,0 +1,76 @@ +--- +updated_at: September 13, 2026 +title: Policy +html_title: Policy +description: "What is allowed: issuance, assignment, access, and lifecycle rules, and where each one lives in the Console today." +kind: concept +--- + +A policy is a rule the platform evaluates to decide something about a credential: +whether an authority will sign it, who gets it, what its holder may do, and what happens to it when a device changes state. +Four kinds, distinguished by *when* they are evaluated. + +## The four kinds + +| Kind | Question | Evaluated | Lives on | +|---|---|---|---| +| **Issuance policy** | Will this authority sign this? | At signing, in the authority | The authority, an issuance method, or an ACME account | +| **Assignment policy** | Which devices and users get this credential? | When a device's configuration is computed | The credential | +| **Access policy** | May this holder do this action on this resource now? | At the verifier, per login or per request | The resource or verifier | +| **Lifecycle policy** | What moves a device between states, and what happens to its credentials? | On an event: an enrollment, an admin action | The team | + +Keeping issuance separate from assignment matters: +the authority is the last line of defense and must be able to refuse what the rest of the platform asked for. +Keeping lifecycle separate from access matters too: +quarantining a device is a state change with consequences for every credential it holds, not a per-request decision. + +## What exists today + +**Issuance policy.** +Allow and deny rules over the names an authority will sign: DNS names, IP addresses, email addresses, URIs, common names, SSH principals. +On a hosted authority they can be set at the authority, per issuance method, and per ACME account. +The rules and their evaluation are documented on the open-source [Policies](../../step-ca/policies.mdx) page, which applies to hosted authorities as well. + +**Assignment policy.** +On every credential: match on assurance (*high* or *normal*), ownership (company or user), operating system, source, and tags, and optionally require a bound user. +An empty policy selects every device. +The Wi-Fi guide's [credential step](../../tutorials/protect-wireless-networks.mdx#create-the-credential) shows the fields. + +**Access policy.** +Two places today. +For SSH hosts, grants map an identity-provider group to hosts with a tag, with or without sudo; the rules are synchronized to each host and enforced at login. +The [access control](../../ssh/acls.mdx) page documents them (shown in the Console under the **SSH Pro** menu today). +For networks, a dedicated RADIUS deployment can return reply attributes, such as a VLAN, chosen by the device's certificate fields or inventory attributes, as the [Wi-Fi guide](../../tutorials/protect-wireless-networks.mdx#option-2-smallstep-enterprise-radius) describes. +The device factor applies a fixed rule: the device must be active and bound to the user signing in. + +**Lifecycle policy.** +The enrollment policy: which sources may add devices and whether they are approved automatically, set in team settings and through `/device-enrollment-policy`. +[Build your inventory](../enrollment-guide.mdx) explains the approval step. + +## How it relates + +```mermaid +flowchart LR + issuance["Issuance policy"] -->|guards| authority["Authority"] + assignment["Assignment policy"] -->|selects devices for| credential["Credential"] + access["Access policy"] -->|decides at| verifier["Verifier"] + lifecycle["Lifecycle policy"] -->|moves| state["Device state"] + authority --> credential --> state --> verifier +``` + +## Where it appears + +- **Console**: each policy is on the object it governs. + Assignment policy on the credential; SSH access rules under the SSH configuration; the enrollment policy under **Settings**; issuance policy on the authority. + There is no **Policy** tab today. +- **API**: `policy` on [`/credentials`](https://gateway.smallstep.com/v2025-01-01/operations/PostCredentials); `/device-enrollment-policy`; `/grants` in the 2023 API for SSH. + See [Smallstep API](../smallstep-api.mdx). + +A cross-cutting Policy view, with every policy able to run in Off, Monitor, or Enforce mode and record its decisions, is planned and not available today. + +## Guides that use it + +- [Wi-Fi](../../tutorials/protect-wireless-networks.mdx): the assignment policy on the credential and, with a dedicated RADIUS deployment, VLAN reply attributes. +- [SSH access control](../../ssh/acls.mdx): grants over groups and host tags. +- [Build your inventory](../enrollment-guide.mdx): the enrollment policy. +- Related concepts: [Credentials](./credentials.mdx), [Inventory](./inventory.mdx), [Verifiers](./verifiers.mdx), and [Audit](./audit.mdx), where decisions are recorded. diff --git a/platform/concepts/trust.mdx b/platform/concepts/trust.mdx new file mode 100644 index 00000000..19178afe --- /dev/null +++ b/platform/concepts/trust.mdx @@ -0,0 +1,66 @@ +--- +updated_at: September 13, 2026 +title: Trust +html_title: Trust +description: "What the team trusts and who relies on it: authorities, issuance methods, trust roots, and the certificates they have issued." +kind: concept +--- + +Trust is your team's cryptographic estate: +the authorities that sign certificates, the ways a certificate can be obtained from each, the trust roots a verifier needs to accept what they sign, and every certificate they have issued. +It answers the question every use case ends with: who trusts whom, and why. + +## The objects + +**Authority.** +A certificate authority the team owns or links. +A *hosted* authority runs on the platform; Smallstep holds its signing keys in a cloud key management service. +An authority created with *your own root* is a hosted intermediate signed by a root you keep. +A *linked* authority is a `step-ca` you run yourself, registered with the platform so its issuance methods and admins are managed here. +Each team also has an attestation authority, which verifies device attestations rather than issuing certificates for resources. +Every hosted authority is a `step-ca`; [How Smallstep hosts step-ca](../../learn/how-smallstep-hosts-step-ca.mdx) says what that shares with the open-source project. + +**Issuance method.** +How a requester obtains a certificate from an authority: hardware-attested (ACME device attestation), standard ACME, SCEP for an MDM, single sign-on (OIDC) for people, cloud instance identity, JWK for pipelines, Kubernetes service account. +The open-source word is *provisioner*, and that is what the API and the Advanced view call it; the types are documented on the open-source [Provisioners](../../step-ca/provisioners.mdx) page. + +**Trust roots.** +The root, usually with the intermediate, as a PEM bundle a verifier can install. +Available on each authority's page and at `https:///roots.pem`. +[Trust roots and chains](../../learn/trust-roots-and-chains.mdx) explains why a verifier needs them. + +**Certificate.** +An issued leaf, X.509 or SSH, with its authority, issuance method, subject, validity, and status. +Certificates can be searched, inspected, revoked, and, for the ones the agent does not manage, renewed and downloaded. + +## How it relates + +```mermaid +flowchart LR + root["Root"] -->|signs| authority["Authority
(intermediate)"] -->|via an issuance method| cert["Certificate"] + authority -.->|trust roots| verifier["Verifier
(RADIUS, IdP, sshd, app)"] -->|checks| cert + cred["Credential
(template + method + policy)"] -->|issued under| authority +``` + +A credential names the authority it is issued under. +A verifier holds that authority's trust roots. +The certificate the device presents chains to the root the verifier holds. +That dotted edge, the verifier relying on the authority, is placed by hand today, once per verifier; the guides say where. + +## Where it appears + +- **Console**: **Authorities** and **Certificates** under the **Certificate Manager** menu. + An authority's page shows its issuance methods (labelled provisioners), its trust roots, and its settings; the certificates list shows X.509 and SSH certificates with search, revoke, and download. +- **API**: `/authorities`, `/authorities/{id}/provisioners`, and [`/certificates`](https://gateway.smallstep.com/v2025-01-01/operations/ListCertificates). + See [Smallstep API](../smallstep-api.mdx). + +A **Trust** tab that groups authorities into zones and records which verifier relies on which authority is planned and not available today. + +## Guides that use it + +- [Create a hosted authority](../../certificate-manager/getting-started.mdx) and [bring your own root](../../certificate-manager/byo-root.mdx). +- Issuance methods: [ACME](../../certificate-manager/acme/README.mdx) and [single sign-on certificates](../../certificate-manager/oidc.mdx). +- [Issue certificates with your own clients](../../certificate-manager/basic-ops.mdx), the general-PKI job. +- [Registration authorities](../../registration-authorities/README.mdx) in front of a hosted authority, and [ACME for Google CAS](../../registration-authorities/acme-for-cas.mdx). +- Every use-case guide has a trust-roots step; [Wi-Fi](../../tutorials/protect-wireless-networks.mdx#find-your-authority) starts by finding the authority. +- Related concepts: [Credentials](./credentials.mdx) are issued under an authority; [Verifiers](./verifiers.mdx) hold its trust roots. diff --git a/platform/concepts/verifiers.mdx b/platform/concepts/verifiers.mdx new file mode 100644 index 00000000..77d2cde8 --- /dev/null +++ b/platform/concepts/verifiers.mdx @@ -0,0 +1,64 @@ +--- +updated_at: September 13, 2026 +title: Verifiers +html_title: Verifiers +description: "What checks a credential at the resource: Smallstep RADIUS, your own RADIUS, the device factor, relays, and your own apps and hosts." +kind: concept +--- + +A verifier is the thing that checks a credential when a device, user, or workload presents it. +It holds the trust roots of the authority that issued the credential, completes the handshake, and decides. +Some verifiers are run by Smallstep; the rest are yours, configured from a guide. + +## The kinds + +**Smallstep RADIUS.** +The verifier for Wi-Fi and wired networks. +Your access points and switches relay the EAP-TLS handshake to it; it validates the full chain against your client CA and checks revocation on every authentication. +Two forms: a multi-tenant service you create yourself with the API (**Managed RADIUS** in the guides), and a dedicated deployment with static IPs, RadSec, reply attributes for VLAN assignment, and authorization webhooks (**Enterprise RADIUS**, provisioned by Smallstep for your team). +[RadSec](../../learn/radsec.mdx) explains the transport. + +**Your own RADIUS.** +FreeRADIUS, Cisco ISE, Aruba ClearPass, NPS, or any server that speaks EAP-TLS, given your authority's trust roots. + +**The device factor.** +Your identity provider, configured to require a Smallstep device certificate at sign-in so that a session is only issued to a person on an enrolled device. +The identity provider is the verifier; Smallstep supplies the certificate and the trust roots. + +**Relays.** +A Smallstep-run MASQUE relay that accepts connections only from devices with a valid certificate and forwards them to resources that cannot verify certificates themselves. +Provisioned by Smallstep for your team. + +**Your own apps and hosts.** +A web server or SaaS app that verifies client certificates (mutual TLS); an SSH host whose `sshd` trusts your user CA, with or without the step-ssh package; a service that checks a workload's certificate. + +An MCP gateway that puts your MCP servers behind device identity is planned and not generally available today. + +## How it relates + +```mermaid +flowchart LR + device["Device with a credential"] -->|presents certificate| verifier["Verifier"] -->|allows or rejects| resource["Resource"] + verifier -->|records| log["Audit"] + authority["Authority
(Trust)"] -.->|trust roots| verifier +``` + +Every verifier needs the authority's trust roots before it can accept anything, and, for Wi-Fi, the device needs the verifier's CA too. +[Trust roots and chains](../../learn/trust-roots-and-chains.mdx) lists where each verifier takes them. +Some verifiers also apply an access policy after the certificate checks out: an SSH host decides whether this user may log in here; a RADIUS server with reply attributes decides which VLAN. +[Policy](./policy.mdx) covers that. + +## Where it appears + +- **Console**: RADIUS servers and the resources they protect are under **Protect**; the identity provider for the device factor is configured with the SSO integration; relays are provisioned by Smallstep. +- **API**: [`/managed-radius`](https://gateway.smallstep.com/v2025-01-01/operations/PostManagedRadius) creates a RADIUS server; `/protect/wifi` and `/protect/ethernet` reference the server CA; `/sso` sets the identity provider. + See [Smallstep API](../smallstep-api.mdx). + +## Guides that use it + +- [Wi-Fi](../../tutorials/protect-wireless-networks.mdx#step-2-configure-the-enforcement-point) and [wired networks](../../tutorials/protect-wired-networks.mdx): Smallstep RADIUS or your own. +- [Web apps](../../tutorials/browser-certificate-setup-guide.mdx): your app or identity provider as the verifier. +- [Relays](../../tutorials/configure-enterprise-relay.mdx). +- [SSH hosts](../../ssh/hosts.mdx) and [access control](../../ssh/acls.mdx): `sshd` with the step-ssh package. +- [VPN](../../tutorials/vpn-setup-guide.mdx): strongSwan, F5, or Azure VPN Gateway verifying device certificates. +- Related concepts: [Trust](./trust.mdx) supplies the roots; [Audit](./audit.mdx) receives the decisions. diff --git a/start-here/for-coding-agents.mdx b/start-here/for-coding-agents.mdx index c9aa5129..838f6a0a 100644 --- a/start-here/for-coding-agents.mdx +++ b/start-here/for-coding-agents.mdx @@ -2,7 +2,78 @@ updated_at: September 13, 2026 title: For coding agents html_title: For coding agents -description: How an agent reads these docs: llms.txt, Markdown per page, the docs MCP, and one skill per use case. +description: What an AI coding agent can read and call today, what is planned, and a prompt to paste. +kind: reference --- -Everything on this site will be readable by an agent: an index at `llms.txt`, every page as Markdown, a docs MCP endpoint, and one skill per use-case guide. This page describes them once they exist. +This page is for people who set up Smallstep with an AI coding agent beside them, and for the agents themselves. +It says what exists today, and, separately, what is planned. + +## What exists today + +### The documentation is Markdown source on GitHub + +Every page on this site is an MDX file in the public repository [github.com/smallstep/docs](https://github.com/smallstep/docs). +An agent can fetch any page as raw text. +The path in the repository matches the URL: +`https://smallstep.com/docs/tutorials/protect-wireless-networks` is `tutorials/protect-wireless-networks.mdx`. + +```text +https://raw.githubusercontent.com/smallstep/docs/main/tutorials/protect-wireless-networks.mdx +``` + +The sidebar tree is `manifest.json` in the same repository; it lists every page in order. + +### An `llms.txt` for the company site + +[smallstep.com/llms.txt](https://smallstep.com/llms.txt) exists. +It indexes the product and platform pages of the marketing site, not this documentation. +Use it for orientation; use the repository for the docs. + +### The API has a published specification + +The [Smallstep API](../platform/smallstep-api.mdx) is a versioned REST API with an OpenAPI specification. +Every operation has a stable reference URL, for example [Create Wi-Fi](https://gateway.smallstep.com/v2025-01-01/operations/PostWifi). +The guides on this site use `curl` against it, so an agent can follow a guide literally. +The same objects are available through the [Terraform provider](https://registry.terraform.io/providers/smallstep/smallstep/latest/docs). + +### The `step` CLI reference + +The [step CLI reference](../step-cli/reference/README.mdx) is generated from the CLI itself and is complete for every command and flag. + +## A prompt to paste + +Give your agent the guide for your use case and an API token with the scopes the guide names. +For Wi-Fi: + +```text +Read https://raw.githubusercontent.com/smallstep/docs/main/start-here/quickstart.mdx +and https://raw.githubusercontent.com/smallstep/docs/main/tutorials/protect-wireless-networks.mdx. +Help me set up certificate-based Wi-Fi with Smallstep. +My API token is in the environment variable SMALLSTEP_API_TOKEN. +Before each API call, show me the request and wait for my go-ahead. +Do not change my access point; tell me what to enter. +``` + +Two habits make this go well. +Ask the agent to show each request before it sends it, because a credential or a RADIUS server is a real object once created. +And keep the access-point change in your own hands; the guide tells the agent which values to hand you. + +## Planned + + + Not available yet +
+ The items in this section are part of the documentation redesign and are not live. + Do not build against them until this page says they exist. +
+
+ +- **Markdown for every page at a predictable URL**, so an agent reads the rendered page rather than the MDX source. +- **A generated `llms.txt` and `llms-full.txt`** for this documentation, built from the manifest, replacing the marketing-site index above for docs work. +- **A public docs MCP endpoint** that answers a search and returns a page. + This is distinct from the customer-facing MCP gateway product. +- **One skill per use-case guide**, whose steps are the guide's steps, published under a discoverable index. +- **Open-in-agent affordances** on every page: copy as Markdown, open in Claude, ChatGPT, or Cursor. + +When these land, this page will say so, and the prompt above will shrink to a single link. diff --git a/start-here/how-smallstep-works.mdx b/start-here/how-smallstep-works.mdx new file mode 100644 index 00000000..34974b5a --- /dev/null +++ b/start-here/how-smallstep-works.mdx @@ -0,0 +1,119 @@ +--- +updated_at: September 13, 2026 +title: How Smallstep works +html_title: How Smallstep works +description: The loop from enrollment to verification, and the five surfaces of the platform, on one page. +kind: learn +--- + +Smallstep gives every device, person, and workload in your organization a certificate that proves what it is, +puts that certificate in front of the things you want to protect, +and records what happened. +Everything else on this site is a detail of that loop. + +## The loop + +A device enrolls and becomes part of your inventory. +An authority issues it a credential. +Something delivers that credential to the device and keeps it current. +The device presents the credential to a resource, and a verifier checks it. +The result is recorded. +Then the credential renews, or is revoked, and the loop continues. + +```mermaid +flowchart LR + enroll["1. Enroll
device joins the inventory"] --> issue["2. Issue
an authority signs a credential"] + issue --> deliver["3. Deliver
agent or MDM installs it"] + deliver --> verify["4. Verify
a verifier checks it at the resource"] + verify --> record["5. Record
the event lands in Audit"] + record -->|renew or revoke| issue +``` + +Each step of the loop has a question behind it, and each question has a surface in the Console and the API. + +| Step | Question | Surface | +|---|---|---| +| Enroll | What do we have? | Inventory | +| Issue | What do we trust, and who relies on it? | Trust | +| Deliver | What are we protecting, with which credential, delivered how? | Protect and Credentials | +| Verify | What is allowed? | Policy | +| Record | What happened? | Audit | + +## The five surfaces + +### Inventory + +Inventory is the set of devices your team knows about and the users bound to them. +A device gets in by enrolling with the Smallstep agent, by syncing from your MDM, or through the API. +Each device carries an assurance level that says how strongly its identity was proven. +Only devices in the inventory can receive credentials. +In the Console this is the **Devices** tab and the **Users** tab. +Read [Inventory](../platform/concepts/inventory.mdx). + +### Trust + +Trust is your cryptographic estate: +the authorities that sign certificates, the ways a certificate can be obtained from them, and the trust roots a verifier needs to accept what they sign. +Smallstep hosts authorities for you, and you can bring your own root. +Every hosted authority runs the open-source `step-ca`, so the mechanics are documented once, in the [step-ca section](../step-ca/README.mdx). +In the Console this is **Authorities** and **Certificates** (under the **Certificate Manager** menu today). +Read [Trust](../platform/concepts/trust.mdx). + +### Protect and Credentials + +A **resource** is the thing you protect: +a Wi-Fi network, a wired network, a VPN, a web app, your SSH hosts, a workload's clients. +A **credential** is the certificate a device, user, or host gets so that it can reach the resource. +It is defined by a certificate template, an issuance method, and an assignment policy that says who gets it. +Something delivers the credential: +the Smallstep agent, an MDM profile, the step-ssh host package, or a manual step. +In the Console, resources live under **Protect** and credentials have their own list (labelled **Endpoints**, under the same menu as Authorities today). +Read [Credentials](../platform/concepts/credentials.mdx) and [Verifiers](../platform/concepts/verifiers.mdx). + +### Policy + +A policy is a rule the platform evaluates about a credential: +whether an authority will sign it, which devices and users get it, what its holder may do, and what happens to it when a device changes state. +Today each policy lives on the object it governs. +The assignment policy is on the credential, the enrollment policy is in team settings, and SSH access rules are on the SSH configuration. +Read [Policy](../platform/concepts/policy.mdx). + +### Audit + +Audit is the record: +every certificate issued, every authentication accepted or rejected, every device that enrolled, every SSH session. +Each device page shows its own activity, and the **Audit** tab shows all of it with one set of filters. +Webhooks push selected events to your own systems. +Read [Audit](../platform/concepts/audit.mdx). + +## One example: a laptop joins the Wi-Fi + +1. A MacBook enrolls with the agent. + The agent proves, using the Secure Enclave, that it is the device your MDM says it is, and the device appears in **Devices** as high assurance. +2. You create a Wi-Fi resource under **Protect**, with a credential whose assignment policy selects company-owned laptops. +3. The agent on that MacBook requests the credential. + Your hosted authority checks the attestation and signs a certificate whose private key never leaves the Secure Enclave. +4. The agent installs the certificate and the network profile. + Nobody types a password. +5. The MacBook connects. + The access point hands the handshake to Smallstep RADIUS, which checks the certificate against your authority's trust roots and answers Access-Accept. +6. The accept appears on the Wi-Fi resource's activity and in **Audit**. +7. Before the certificate expires, the agent renews it. + If the device is retired, its certificates are revoked and the next attempt is rejected. + +The [Quickstart](./quickstart.mdx) walks this path with real commands. + +## Why it is built this way + +The loop only works if step 1 is strong. +A certificate that can be copied to another machine proves nothing about the machine. +Smallstep binds each credential to a key that lives in the device's secure hardware, and requires the device to attest to that binding before an authority signs anything. +That is the difference between "a device that has a certificate" and "this device". +[Why device identity](../learn/why-device-identity.mdx) makes the argument; [Attestation explained](../learn/attestation-explained.mdx) shows the mechanism. + +## Where to go next + +- **Evaluating?** Start with [Why device identity](../learn/why-device-identity.mdx) and read through the Learn section. +- **Building?** Follow the [Quickstart](./quickstart.mdx), then the guide for your use case, beginning with [Wi-Fi](../tutorials/protect-wireless-networks.mdx). +- **Operating?** Read the six [Concepts](../platform/concepts/README.mdx) pages, then [build your inventory](../platform/enrollment-guide.mdx). +- **Running your own CA?** The open-source [step-ca](../step-ca/README.mdx) section stands on its own; [How Smallstep hosts step-ca](../learn/how-smallstep-hosts-step-ca.mdx) explains what the platform adds. diff --git a/start-here/quickstart.mdx b/start-here/quickstart.mdx index 6fa449eb..534f3f99 100644 --- a/start-here/quickstart.mdx +++ b/start-here/quickstart.mdx @@ -2,7 +2,150 @@ updated_at: September 13, 2026 title: Quickstart html_title: Quickstart -description: Your first device and your first credential in about twenty minutes. +description: Your first device and your first credential, on Wi-Fi, in about twenty minutes plus your access-point change. +kind: guide --- -The shortest path from a team with devices to one device that just got onto a resource with a certificate. It is being written as part of the docs redesign; until it lands, start with the [Wi-Fi guide](../tutorials/protect-wireless-networks.mdx). +The shortest path from a team with devices to one device that joined a Wi-Fi network with a certificate instead of a password. +This page condenses the [Wi-Fi guide](../tutorials/protect-wireless-networks.mdx). +Go there for MDM-managed clients, per-vendor access-point instructions, and troubleshooting. + + +
+ Use a test SSID for this walk-through. + Do not change a production network until you have seen a device join. +
+
+ +## What you get + +At the end you have: + +- A **credential** that issues a client certificate to each of your devices, with the private key generated in the device's secure hardware. +- A **RADIUS server** run by Smallstep that verifies those certificates during the EAP-TLS handshake. +- A **Wi-Fi resource** that tells the agent which network to configure and which RADIUS server to trust. +- One device on the network, and its Access-Accept visible in the Console. + +```mermaid +graph LR + cred["Credential
(client certificate)"] --> network["Wi-Fi resource
(SSID and trust)"] --> device["Device with the agent"] + radius["Smallstep RADIUS"] -->|server CA| network + radius -->|"IP, port, shared secret"| ap["Access point"] +``` + +## Before you start + +You need: + +1. A Smallstep team, and at least one device [enrolled in your inventory](../platform/enrollment-guide.mdx) with the [Smallstep agent](../platform/smallstep-agent.mdx) installed on macOS, Windows, or Linux. + The device must be approved. +2. The authority that will sign your client certificates. + Open **Authorities** in the Console (under the **Certificate Manager** menu) and note the **Authority ID**; download its root certificate as `client_ca.crt`. +3. An [API token](https://smallstep.com/app/?next=/settings/api/tokens/add). + This quickstart uses the API because every value it needs is in one response; the same objects can be created under the **Protect** tab. +4. The public IP address your access points or wireless controller send RADIUS traffic from. +5. Admin access to the access point and a test SSID. + +Store the token in a headers file for `curl`: + +```bash +set +o history +echo "Authorization: Bearer [your API token]" > api_headers +set -o history +``` + +## Create the network + +Three calls: the credential, the RADIUS server, and the Wi-Fi resource. + +### 1. Create the credential + +The credential names the authority, the certificate shape, and the devices that get it. +Copy the request body from the Wi-Fi guide's [Create the credential](../tutorials/protect-wireless-networks.mdx#create-the-credential) step, which selects high-assurance macOS, Windows, and Linux devices and asks for a hardware-attested key, save it as `credential.json`, and post it: + +```bash +curl -sH @api_headers --request POST \ + --url https://gateway.smallstep.com/api/credentials \ + --header 'Accept: application/json' \ + --header 'Content-Type: application/json' \ + --header 'x-smallstep-api-version: 2025-01-01' \ + --data @credential.json | jq +``` + +Save the `id` from the response as your credential ID. + +### 2. Create the RADIUS server + +Register the public IP your access points use and the root you downloaded, so the server can verify your client certificates: + +```bash +jq -n --rawfile ca client_ca.crt \ + '{name: "Quickstart RADIUS", nasIPs: ["203.0.113.10"], clientCA: $ca}' \ +| curl -sH @api_headers --request POST \ + --url https://gateway.smallstep.com/api/managed-radius \ + --header 'Accept: application/json' \ + --header 'Content-Type: application/json' \ + --header 'x-smallstep-api-version: 2025-01-01' \ + --data @- | jq +``` + +From the response, keep `serverIP`, `serverPort`, and `serverHostname`, and save `serverCA` to `radius_ca.crt`. +Then fetch the shared secret: + +```bash +curl -sH @api_headers --request GET \ + --url "https://gateway.smallstep.com/api/managed-radius/[your RADIUS server ID]?secret=true" \ + --header 'Accept: application/json' \ + --header 'x-smallstep-api-version: 2025-01-01' | jq -r '.secret' +``` + +Treat the secret like a password. + +### 3. Create the Wi-Fi resource + +```bash +jq -n --rawfile ca radius_ca.crt \ + '{ + ssid: "[your test SSID]", + hidden: false, + autojoin: true, + radiusServerCA: $ca, + radiusServerDomain: "[serverHostname from step 2]", + credentials: ["[your credential ID]"] + }' \ +| curl -sH @api_headers --request POST \ + --url https://gateway.smallstep.com/api/protect/wifi \ + --header 'Accept: application/json' \ + --header 'Content-Type: application/json' \ + --header 'x-smallstep-api-version: 2025-01-01' \ + --data @- | jq +``` + +The resource now appears under [Protect → Wi-Fi](https://smallstep.com/app/?next=/protect/wifi). + +## Point your access points at Smallstep + +On the access point or controller, set the test SSID to WPA2 Enterprise or WPA3 Enterprise and enter the RADIUS server's IP, port, and shared secret from step 2. +The Wi-Fi guide has [per-vendor instructions](../tutorials/protect-wireless-networks.mdx#access-point-configuration-reference) for UniFi, Aruba, Cisco, Meraki, Juniper Mist, MikroTik, and others. + +## Deliver + +For a device running the agent there is nothing to do. +On its next sync the agent requests the certificate with a key generated in the device's secure hardware, trusts the RADIUS server CA for this network, creates the network profile, and renews the certificate before it expires. + +If the device is managed by an MDM without the agent, follow the [MDM-managed clients](../tutorials/protect-wireless-networks.mdx#mdm-managed-clients) section of the Wi-Fi guide instead. + +## Verify + +1. On the test device, select the SSID. + It should connect without asking for a password. +2. In the Console, open the Wi-Fi resource under **Protect → Wi-Fi**. + The issued certificate and the authentication activity for the device appear there. + +If the device does not connect, work through [Verify and troubleshoot](../tutorials/protect-wireless-networks.mdx#verify-and-troubleshoot) in the Wi-Fi guide and the [agent troubleshooting page](../platform/troubleshooting-agent.mdx). + +## Next + +- Roll out to more devices by widening the credential's assignment policy; the same credential can serve a [wired network](../tutorials/protect-wired-networks.mdx) too. +- Read [How Smallstep works](./how-smallstep-works.mdx) to see where each object you just created lives. +- Automate the same three objects with the [Terraform provider](https://registry.terraform.io/providers/smallstep/smallstep/latest/docs).