<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>

<rfc xmlns:xi="http://www.w3.org/2001/XInclude" category="std" docName="draft-ietf-sshm-ssh-agent-16" number="9987"  ipr="trust200902" obsoletes="" updates="" consensus="true" submissionType="IETF" xml:lang="en" sortRefs="false" symRefs="true" tocInclude="true" version="3">

<front>
  <title abbrev="SSH Agent Protocol">Secure Shell (SSH) Agent Protocol</title>

<!-- [rfced] Please note that the title of the document has been
     updated as follows:

Abbreviations have been expanded per Section 3.6 of RFC 7322 ("RFC
Style Guide"). Please review.

Original:
SSH Agent Protocol

Current:
Secure Shell (SSH) Agent Protocol
-->

  
  <seriesInfo name="RFC" value="9987"/>
  <author fullname="Damien Miller" initials="D." surname="Miller">
    <organization>OpenSSH</organization>
    <address>
      <email>djm@openssh.com</email>  
      <uri>https://www.openssh.com/</uri>
    </address>
  </author>
  <date month="May" year="2026"/>
  <area>SEC</area>
  <workgroup>sshm</workgroup>

  <keyword>ssh</keyword>
  <keyword>agent</keyword>
  <keyword>ssh-agent</keyword>

  <abstract>
    <t>
		This document specifies a key agent protocol for use in
		the Secure Shell (SSH) protocol.
		</t>
	</abstract>
</front>

<middle>
<section><name>Introduction</name>
	<t>
	Secure Shell (SSH)
	<xref target="RFC4251" />
	is a protocol for secure remote connections
	<xref target="RFC4253" />
	and login
	<xref target="RFC4254" />
	over untrusted networks.
	It supports multiple authentication mechanisms
	<xref target="RFC4252" />
	including public key authentication. This document
	specifies the protocol for interacting with a key
	management component, usually referred to as "an agent",
	that holds private keys. SSH clients (and possibly
	SSH servers) can invoke the agent via this protocol
	to perform operations using public and private keys
	held in the agent.
	</t>
	<t>
	Holding keys in an agent offers usability and security
	advantages to loading and unwrapping them at each use, as
	each key unwrapping may require entry of a passphrase.
	Access to an agent may optionally be forwarded across an SSH connection,
	thereby allowing remote systems to use stored keys without directly
	exposing the key material to the remote system.
	Finally, the agent may be implemented as a dedicated component that
	presents a smaller attack surface than a key loaded into
	a full SSH server or client and that may be subject to special
	protection from the wider system.
	</t>
	</section>      
	<section anchor="requirements"><name>Requirements Language</name>
        <t>
    The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
    NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
    "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
    described in BCP&nbsp;14 <xref target="RFC2119"/> <xref target="RFC8174"/> 
    when, and only when, they appear in all capitals, as shown here.
        </t>

	</section>
    
<section><name>Protocol Overview</name>
	<t>
	The agent protocol is a packetised request-response protocol that is
	solely driven by the client. It consists of a number of
	requests sent from a client to an agent and a set of reply
	messages that are sent in response. At no time does the agent
	send messages except in response to a client request. Replies
	are sent in order.
	</t>
	<t>
	These requests include the ability to load keys into an agent,
	remove some or all keys from an agent, and perform signature
	operations using previously loaded keys.
	</t>
	<t>
	Agents <bcp14>MAY</bcp14> implement support for only a subset of available key types
	and <bcp14>MAY</bcp14> additionally refuse some operations in particular contexts.
	For example, an agent may allow only clients local to itself to
	add keys or may make particular subsets of keys available to a
	given client.
	For this reason, clients of the agent <bcp14>SHOULD</bcp14> be prepared to
	fail gracefully if any operation is refused.
	</t>
	</section>
	<section><name>Terminology and Units</name>
		<t>
		Henceforth, in this document, "agent" will be used to refer to a
		key management component that implements the responder side of
		this protocol. "Client" will refer to a tool that implements
		the requester side of the protocol to communicate with an agent.
		If it is pertinent that the client in question is a
		Secure Shell client as described in <xref target="RFC4251"/>, then the client will be
		explicitly referred to as an "SSH client".
		Similarly, "SSH server" will be used to refer to Secure Shell
		servers.
		</t>
		<t>
		All encoding data types ("byte", "uint32", "string", etc.) are
		as specified in <xref target="RFC4251" section="5" />.
		Additionally, the type "byte[]" without a specified length
		within the square brackets indicates an unadorned sequence of
		zero or more bytes where the length is determined by context.
		</t>
		<t>
		All length units are given in bytes unless otherwise specified.
		</t>
	</section>
    
<section anchor="protomess"><name>Protocol Messages</name>
	<t>
	Messages consist of a "length", "type", and "contents".
	</t>
	<sourcecode><![CDATA[
    uint32            length
    byte              type
    byte[length - 1]  contents]]></sourcecode>

	<t>
	In the sections below, the "length" field is omitted. For
	clarity, the symbolic names of the message types are shown;
	their numeric values are listed in <xref target="messagenum"/>.
	</t>

	<section anchor="genericresp"><name>Generic Agent Responses</name>
		<t>
		The following generic messages may be sent by the agent
		in response to requests from the client. On success, the
		agent <bcp14>MUST</bcp14> reply either with the single-byte response:
		</t>
		<sourcecode><![CDATA[
    byte              SSH_AGENT_SUCCESS]]></sourcecode>

		<t>
		or with a request-specific success message that may contain
		additional fields.
		On failure, the agent <bcp14>MUST</bcp14> reply with the single-byte response:
		</t>
		<sourcecode><![CDATA[
    byte              SSH_AGENT_FAILURE]]></sourcecode>

		<t>
		or with a request-specific failure message that may contain
		additional fields.
		SSH_AGENT_FAILURE messages <bcp14>MUST</bcp14> also be sent in reply to
		requests with unknown or unsupported types.
		</t>
	</section>
	<section anchor="addkeys"><name>Adding Keys to the Agent</name>
		<t>
		Keys may be added to the agent using the
		SSH_AGENTC_ADD_IDENTITY or
		SSH_AGENTC_ADD_ID_CONSTRAINED messages.
		The latter variant allows adding keys with
		optional constraints on their usage.
		</t>
		<t>
		The generic format for the
		SSH_AGENTC_ADD_IDENTITY message is:
		</t>
		<sourcecode><![CDATA[
    byte             SSH_AGENTC_ADD_IDENTITY
    string           key type
    byte[]           key data
    string           comment]]></sourcecode>
		<t>
		Here "key type" is the specified key type name, for example,
		"ssh-rsa" for an RSA key as defined by
		<xref target="RFC4253" />.
		The "key data" consists of the public and private components
		of the key and varies by key type, as specified in Sections
		<xref target="add-dsa" format="counter" /> through
		<xref target="add-rsa" format="counter" />
		for commonly used key types.
		A "comment" is
		a human-readable key name or comment
		as a UTF-8 string that may serve to identify the
		key in user-visible messages. This string may be of zero length.
		</t>
		<t>
		The SSH_AGENTC_ADD_ID_CONSTRAINED message is similar
		but adds an extra field:
		</t>
		<sourcecode><![CDATA[
    byte             SSH_AGENTC_ADD_ID_CONSTRAINED
    string           key type
    byte[]           key data
    string           comment
    constraint[]     constraints]]></sourcecode>
		<t>
		Constraints are used to place limits on the validity
		or use of keys.
		<xref target="constraints" /> details constraint types
		and their formats.
		Clients <bcp14>SHOULD</bcp14> prefer the SSH_AGENTC_ADD_IDENTITY message
		over sending an SSH_AGENTC_ADD_ID_CONSTRAINED message with an empty
		"constraints" field, though both are valid and equivalent.
		</t>
		<t>
		An agent <bcp14>MUST</bcp14> reply with SSH_AGENT_SUCCESS
		if the key was successfully loaded
		as a result of one of these messages or
		SSH_AGENT_FAILURE otherwise.
		</t>
		<t>

		  
		Adding a key that is already present in an agent <bcp14>SHOULD</bcp14> replace
		any constraints it was previously loaded with those (if any)
		that are present in the subsequent add request, as this ensures that
		security-relevant constraints on a loaded key best match user
		expectations. Otherwise, an agent <bcp14>MAY</bcp14> refuse to load a key that
		has already been loaded.
		</t>
		<t>
		An agent <bcp14>MAY</bcp14> support only a subset of the key types defined
		here and <bcp14>MAY</bcp14> support additional key types as described below.
		If an agent does not recognise the type name in a request to
		add a key, then it <bcp14>MUST</bcp14> respond with an SSH_AGENT_FAILURE reply.
		</t>
		<section anchor="add-dsa"><name>DSA Keys</name>
			<t>
			Digital Signature Algorithm (DSA) keys have key type "ssh-dss" and are
			defined in <xref target="RFC4253" />. They
			may be added to the agent using the following
			message. The "constraints" field is only
			present for the SSH_AGENTC_ADD_ID_CONSTRAINED
			message.
			</t>
			<sourcecode><![CDATA[
    byte             SSH_AGENTC_ADD_IDENTITY or
                     SSH_AGENTC_ADD_ID_CONSTRAINED
    string           "ssh-dss"
    mpint            p
    mpint            q
    mpint            g
    mpint            y
    mpint            x
    string           comment
    constraint[]     constraints]]></sourcecode>
			<t>
			The "p", "q", and "g" values are the DSA domain
			parameters. The "y" and "x" values are the public and
			private keys, respectively. These values are
			as defined by Section 4.1 of
			<xref target="FIPS.186-4"/>.
			</t>
		</section>
		<section anchor="add-ecdsa"><name>ECDSA Keys</name>
			<t>
			Elliptic Curve Digital Signature Algorithm (ECDSA) keys have key types starting with
			"ecdsa-sha2-" and are defined in
			<xref target="RFC5656" />. They
			may be added to the agent using the
			following message.
			The "constraints" field is only present for
			the SSH_AGENTC_ADD_ID_CONSTRAINED message.
			</t>
			<sourcecode><![CDATA[
    byte             SSH_AGENTC_ADD_IDENTITY or
                     SSH_AGENTC_ADD_ID_CONSTRAINED
    string           key type
    string           ecdsa_curve_name
    string           Q
    mpint            d
    string           comment
    constraint[]     constraints]]></sourcecode>
			<t>
			The values "Q" and "d" are the ECDSA public and
			private values respectively. Both are defined
			by Section 6.2 of <xref target="FIPS.186-5"/>.
			</t>
		</section>
		<section anchor="add-eddsa"><name>EdDSA Keys</name>
		<t>
<!--[rfced] Please review both how we added in an expansion for the
     abbreviation EdDSA and the possible citation add in the following
     text.  Note also that we have updated one instance of "EDDSA" to
     "EdDSA".  Please let us know any objections.
		      
Original:
[RFC8709] defines Ed25519 and Ed448 with key type names "ssh-ed25519"
and "ssh-ed448" respectively.


Current:
[RFC8709] defines Edwards-curve Digital Signature Algorithm (EdDSA)
keys (see [RFC8032]) Ed25519 and Ed448 with key type names
"ssh-ed25519" and "ssh-ed448", respectively.
-->
		  
			<xref target="RFC8709" /> defines Edwards-curve Digital Signature Algorithm (EdDSA) keys (see <xref target="RFC8032"/>) Ed25519 and
			Ed448 with key type names "ssh-ed25519" and
			"ssh-ed448", respectively.
			These may be added to the agent using the
			following message. The "constraints"
			field is only present for
			the SSH_AGENTC_ADD_ID_CONSTRAINED message.
			</t>
			<sourcecode><![CDATA[
    byte             SSH_AGENTC_ADD_IDENTITY or
                     SSH_AGENTC_ADD_ID_CONSTRAINED
    string           "ssh-ed25519" or "ssh-ed448"
    string           ENC(A)
    string           k || ENC(A)
    string           comment
    constraint[]     constraints]]></sourcecode>
			<t>

<!--[rfced] Do we need both "redundant" and "repetition" here?

Original:
...(this redundant repetition of the public key is to maintain
compatibility with widely deployed implementations).

Perhaps:
...(this repetition of the public key is to maintain
compatibility with widely deployed implementations).
-->
			  
			The first value is the EdDSA public key
			ENC(A).
			The second value is a concatenation of
			the private key k
			and the public
			ENC(A) key (this redundant repetition of the public key
			is to maintain compatibility with widely deployed
			implementations).
			The contents and interpretation of the
			ENC(A) and k values are
			defined by <xref target="RFC8032" section="3.2"/>.
			</t>
		</section>
		<section anchor="add-rsa"><name>RSA Keys</name>
			<t>
			RSA keys have key type "ssh-rsa" and are
			defined in <xref target="RFC4253" />. They
			may be added to the agent using the following
			message. The "constraints" field is only
			present for the
			SSH_AGENTC_ADD_ID_CONSTRAINED message.
			</t>
			<sourcecode><![CDATA[
    byte             SSH_AGENTC_ADD_IDENTITY or
                     SSH_AGENTC_ADD_ID_CONSTRAINED
    string           "ssh-rsa"
    mpint            n
    mpint            e
    mpint            d
    mpint            iqmp
    mpint            p
    mpint            q
    string           comment
    constraint[]     constraints]]></sourcecode>
			<t>
			"n" is the public composite modulus.
			"e" is the public exponent.
			"d" is the private exponent.
			"p" and "q" are its constituent private
			prime factors.
			"iqmp" is the inverse of "q" modulo
			"p". All of these values, except "iqmp"
			(which can be calculated from the others),
			are defined by Section 5.1 of
			<xref target="FIPS.186-5" />.
			</t>
		</section>
		<section anchor="add-other"><name>Other Keys</name>
			<t>
			Agents and their clients <bcp14>MAY</bcp14> support additional key
			types not documented here. Vendor-specific key types
			<bcp14>MUST</bcp14> use the domain-qualified naming convention
			defined in <xref target="RFC4251" section="6" />
			until codepoints are allocated by IANA
			<xref target="IANA-PUBKEYS" />.
			</t>
		</section>
		<section anchor="addtoken"><name>Adding Keys from a Token</name>
			<t>
			Keys hosted on smart-cards or other hardware
			tokens may be added using the
			SSH_AGENTC_ADD_SMARTCARD_KEY and
			SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED
			requests. Note that the "constraints" field is only
			included for the
			SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED
			variant of this message.
			</t>
			<sourcecode><![CDATA[
    byte             SSH_AGENTC_ADD_SMARTCARD_KEY or
                     SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED
    string           token id
    string           PIN
    constraint[]     constraints]]></sourcecode>
			<t>
			Here "token id" is an opaque identifier for the
			hardware token and "PIN" is an optional
			password or PIN to unlock the key.
			The interpretation of "token id" is not defined
			by the protocol: it is left solely up to
			the agent.
			</t>
			<t>
			Typically, only the public components of
			any keys supported on a hardware token
			will be loaded into an agent; thus, strictly
			speaking, this message really arranges for
			future private key operations to be
			delegated to the hardware token in question.
			</t>
			<t>
			An agent <bcp14>MUST</bcp14> reply with SSH_AGENT_SUCCESS
			if one or more keys were successfully loaded
			as a result of one of these messages or with
			SSH_AGENT_FAILURE if no keys were found.
			The agent <bcp14>MUST</bcp14> also return SSH_AGENT_FAILURE
			if the "token id" was not recognised, if the request
			was against agent policy, or if
			the agent doesn't support token-hosted keys
			at all.
			</t>
		</section>
		<section anchor="constraints">
		  <name>Key Constraints</name>
			<t>
			A number of constraints may be used in the
			constrained variants of the key add messages.
			Each constraint is represented by a type byte
			followed by zero or more value bytes.
			</t>
			<t>
			Zero or more constraints may be specified when
			adding a key with one of the *_CONSTRAINED
			requests. Multiple constraints are appended
			consecutively to the end of the request:
			</t>
			<sourcecode><![CDATA[
    byte             constraint1_type
    byte[]           constraint1_data
    byte             constraint2_type
    byte[]           constraint2_data
    ....
    byte             constraintN_type
    byte[]           constraintN_data]]></sourcecode>
			<t>
			To fully parse a constraint, it is necessary to
			know its structure beforehand; it is not
			possible to safely recover when an unrecognised
			constraint is encountered.
			Given this, if an agent does not recognise or support a
			requested constraint, it <bcp14>MUST</bcp14> abort parsing, refuse the
			request, and return an SSH_AGENT_FAILURE message to the
			client.
			</t>
			<t>
			The following subsections describe the constraints that have been defined.
			</t>
			<section><name>Key Lifetime Constraint</name>
				<t>
				This constraint requests that the
				agent limit the key's lifetime by
				deleting it after the specified
				duration (in seconds) has elapsed
				from the time the key was added to
				the agent.
				</t>
				<sourcecode><![CDATA[
    byte             SSH_AGENT_CONSTRAIN_LIFETIME
    uint32           seconds]]></sourcecode>
			</section>
			<section><name>Key Confirmation Constraint</name>
				<t>
				This constraint requests that the
				agent require explicit user
				confirmation for each private key
				operation using the key. For example,
				the agent could present a confirmation
				dialog before completing a signature
				operation.
				</t>
				<sourcecode><![CDATA[
    byte             SSH_AGENT_CONSTRAIN_CONFIRM]]></sourcecode>
			</section>
			<section anchor="contraintext"><name>Constraint Extensions</name>
				<t>
				Agents may implement experimental
				or private-use constraints through
				an extension constraint that supports
				named constraints.
				</t>
				<sourcecode><![CDATA[
    byte             SSH_AGENT_CONSTRAIN_EXTENSION
    string           extension name
    byte[]           extension-specific details]]></sourcecode>
				<t>
				The "extension name" <bcp14>MUST</bcp14> consist of
				a UTF-8 string.
				Vendor extensions <bcp14>MUST</bcp14> be suffixed by the
				implementation domain following
				the naming scheme defined in
				<xref target="RFC4251" section="6" />,
				e.g.,  "foo@example.com".
				</t>
				<t>
				Note, given the above requirement to reject
				keys with unsupported constraints, a constraint
				extension is only usable when both the client
				and agent support it. Otherwise, the agent
				will be required to reject the key. This is
				desirable, as the constraint extension may
				specify limits on the key that, if ignored,
				may result in the key being available in
				situations the user did not intend (i.e., the
				agent will fail safely).
				</t>
			</section>
		</section>
	</section>
	<section anchor="pubkeyblob"><name>Public Key Encoding</name>
		<t>
		Keys previously loaded into an agent are referred to by their
		public key blob, which is the standard SSH wire encoding for
		public keys. SSH protocol key encodings are defined in
		<xref target="RFC4253" /> for "ssh-rsa" and "ssh-dss" keys,
		in <xref target="RFC5656" /> for "ecdsa-sha2-*" keys, and in
		<xref target="RFC8709" /> for "ssh-ed25519" and "ssh-ed448"
		keys.
		</t>
	</section>
	<section anchor="rmkeys"><name>Removing Keys from the Agent</name>
		<t>
		A client may request that an agent remove
		all keys that it stores:
		</t>
		<sourcecode><![CDATA[
    byte             SSH_AGENTC_REMOVE_ALL_IDENTITIES]]></sourcecode>
		<t>
		On receipt of such a message,
		an agent <bcp14>SHOULD</bcp14> delete all keys that it is holding
		and reply with SSH_AGENT_SUCCESS; otherwise, it <bcp14>MUST</bcp14>
		reply with SSH_AGENT_FAILURE if the request was refused.
		</t>
		<t>
		This request <bcp14>SHOULD</bcp14> be honoured regardless of
		any agent policy that limits actions that a given
		client may take; otherwise, a user would be unable to
		quickly and completely remove their keys in an urgent situation.
		</t>
		<t>
		Specific keys may also be removed:
		</t>
		<sourcecode><![CDATA[
    byte             SSH_AGENTC_REMOVE_IDENTITY
    string           key blob]]></sourcecode>
		<t>
		Where "key blob" is the standard public key encoding of the
		key to be removed (<xref target="pubkeyblob" />).
		</t>
		<t>
		An agent <bcp14>MUST</bcp14> reply with SSH_AGENT_SUCCESS if the key was
		deleted or SSH_AGENT_FAILURE if it was not found.
		</t>
		<t>
		Token-hosted keys may be removed from an agent using:
		</t>
		<sourcecode><![CDATA[
    byte             SSH_AGENTC_REMOVE_SMARTCARD_KEY
    string           token id
    string           PIN]]></sourcecode>
		<t>
		Where "token id" is an opaque identifier for the hardware token
		and "PIN" is an optional password or PIN (not typically
		used), both encoded using UTF-8.
		Requesting deletion of token-hosted keys <bcp14>SHOULD</bcp14>
		cause the agent to remove all keys it loaded from the device
		matching "token id".
		Similarly to SSH_AGENTC_REMOVE_ALL_IDENTITIES, agents <bcp14>SHOULD</bcp14>
		honour this request regardless of local policy to allow
		fast and complete removal of keys.

<!--[rfced] Please review if any text marked "Note:" should be put in
     the <aside> element (defined as "a container for content that is
     semantically less important or tangential to the content that
     surrounds it" at
     https://authors.ietf.org/en/rfcxml-vocabulary#aside.

Original:
Note: this operation affects the agent only, it SHOULD NOT cause the
keys be deleted from the token itself.

-->

<!--[rfced] Please confirm that the following update maintains your
     intended meaning:

Original:
An agent MUST reply with SSH_AGENT_SUCCESS keys were deleted or
SSH_AGENT_FAILURE if none were found.

Current:
An agent MUST reply with SSH_AGENT_SUCCESS if the keys were deleted or
SSH_AGENT_FAILURE if none were found.

-->
		
		Note: this operation affects the agent only; it <bcp14>SHOULD NOT</bcp14>
		cause the keys be deleted from the token itself.
		</t>
		<t>
		An agent <bcp14>MUST</bcp14> reply with SSH_AGENT_SUCCESS if the keys were
		deleted or SSH_AGENT_FAILURE if none were found.
		</t>
	</section>
	<section anchor="listkeys"><name>Requesting a List of Keys</name>
		<t>
		A client may request a list of keys from an agent using the
		following message:
		</t>
		<sourcecode><![CDATA[
    byte             SSH_AGENTC_REQUEST_IDENTITIES]]></sourcecode>
		<t>
		The agent <bcp14>MUST</bcp14> reply with a message with the following
		preamble:
		</t>
		<sourcecode><![CDATA[
    byte             SSH_AGENT_IDENTITIES_ANSWER
    uint32           nkeys]]></sourcecode>
		<t>
		Where "nkeys" indicates the number of keys to follow.
		Following the preamble are zero or more keys, representing the
		keys the agent makes available to the client with each
		encoded as:
		</t>
		<sourcecode><![CDATA[
    string           key blob
    string           comment]]></sourcecode>
		<t>
		Where "key blob" is the standard public key encoding of the
		key (<xref target="pubkeyblob" />) and "comment" is a
		human-readable comment encoded as a UTF-8 string.
		</t>
	</section>
	<section anchor="privkeyops"><name>Private Key Operations</name>
		<t>
		A client may request that the agent perform a
		private key signature operation using the
		following message:
		</t>
		<sourcecode><![CDATA[
    byte             SSH_AGENTC_SIGN_REQUEST
    string           key blob
    string           data
    uint32           flags]]></sourcecode>
		<t>
		Where "key blob" is the key requested to perform the
		signature (encoded as per <xref target="pubkeyblob" />),
		"data" is the data to be signed, and "flags" is a bitfield
		containing the bitwise OR of zero or more signature flags
		(see below).
		</t>
		<t>
		If the agent does not support the requested flags, or is
		otherwise unable or unwilling to generate the signature
		(for example, because it doesn't have the specified key
		or the user refused confirmation of a constrained key),
		it <bcp14>MUST</bcp14> reply with an SSH_AGENT_FAILURE message.
		</t>
		<t>
		On success, the agent <bcp14>MUST</bcp14> reply with:
		</t>
		<sourcecode><![CDATA[
    byte             SSH_AGENT_SIGN_RESPONSE
    string           signature]]></sourcecode>
		<t>
		The signature format is specific to the algorithm of the key
		type in use.  SSH protocol signature formats are defined in
		<xref target="RFC4253" /> for "ssh-rsa" and "ssh-dss" keys,
		in <xref target="RFC5656" /> for "ecdsa-sha2-*" keys, and in
		<xref target="RFC8709" /> for "ssh-ed25519" and "ssh-ed448"
		keys.
		</t>
		<section><name>Signature Flags</name>
			<t>
			Two flags are currently defined for
			signature request messages:
			SSH_AGENT_RSA_SHA2_256 and SSH_AGENT_RSA_SHA2_512
			(defined in <xref target="sigflagnum" />).
			These two flags are only valid for
			"ssh-rsa" keys and request that the agent
			return a signature using
			the "rsa-sha2-256" or "rsa-sha2-512"
			signature methods, respectively. These
			signature schemes are defined in
			<xref target="RFC8332" />.
		</t>
		</section>
	</section>
	<section anchor="lock"><name>Locking and Unlocking an Agent</name>
		<t>
		The agent protocol supports instructing an agent to
		temporarily lock itself with a passphrase. When locked, an
		agent <bcp14>MUST</bcp14> suspend processing of sensitive operations
		(private key signature operations at the very least) until it
		has been unlocked with the same passphrase.
		</t>
		<t>
		The following message instructs an agent to lock itself:
		</t>
		<sourcecode><![CDATA[
    byte             SSH_AGENTC_LOCK
    string           passphrase]]></sourcecode>
		<t>
		The agent <bcp14>MUST</bcp14> reply with SSH_AGENT_SUCCESS if locked
		successfully or SSH_AGENT_FAILURE otherwise (e.g., if the agent
		was already locked).
		</t>
		<t>
		The following message requests unlocking an agent:
		</t>
		<sourcecode><![CDATA[
    byte             SSH_AGENTC_UNLOCK
    string           passphrase]]></sourcecode>
		<t>
		If the agent is already locked and the passphrase matches the
		one used to lock it, then it <bcp14>MUST</bcp14> unlock and reply with
		SSH_AGENT_SUCCESS. If the agent is already unlocked or if
		the passphrase does not match, it <bcp14>MUST</bcp14> reply with
		SSH_AGENT_FAILURE.
		</t>
	</section>
	<section anchor="extreq"><name>Extension Mechanism</name>
		<t>
		The agent protocol includes an optional extension mechanism
		that allows vendor-specific and experimental messages to be
		sent via the agent protocol. Extension requests from the
		client consist of:
		</t>
		<sourcecode><![CDATA[
    byte             SSH_AGENTC_EXTENSION
    string           extension type
    byte[]           extension request-specific contents]]></sourcecode>
		<t>
		The "extension type" indicates the type of the extension message
		as a UTF-8 string.  Implementation-specific extensions <bcp14>MUST</bcp14>
		be suffixed by the implementation domain following the
		extension naming scheme defined in
		<xref target="RFC4251" section="6" />, e.g., "foo@example.com".
		</t>
		<t>
		An agent that does not support extensions of the supplied type
		<bcp14>MUST</bcp14> reply with an empty SSH_AGENT_FAILURE message. This reply
		is also sent by agents that do not support the extension
		mechanism at all.
		</t>
		<t>
		The contents of successful extension reply messages are
		specific to the "extension type".
		Successful extension requests <bcp14>MUST</bcp14> return
		either SSH_AGENT_SUCCESS on success or an extension-specific
		response message:
		</t>
		<sourcecode><![CDATA[
    byte             SSH_AGENT_EXTENSION_RESPONSE
    string           extension type
    byte[]           extension response-specific contents]]></sourcecode>
		<t>
		Where the "extension type" is the same as that in the request.
		</t>
		<t>
		Extension failure <bcp14>SHOULD</bcp14> be signaled using an
		SSH_AGENT_EXTENSION_FAILURE message:
		</t>
		<sourcecode><![CDATA[
    byte             SSH_AGENT_EXTENSION_FAILURE]]></sourcecode>
		<t>
		Extensions <bcp14>SHOULD NOT</bcp14> use
		the standard SSH_AGENT_FAILURE message. This allows failed
		requests to be distinguished from the extension not being
		supported.
		</t>
		<section anchor="queryext"><name>Query Extension</name>
			<t>
			A single optional extension request "query" is
			defined to allow a client to query which, if any,
			extensions are supported by an agent.
			</t>
		<sourcecode><![CDATA[
    byte             SSH_AGENTC_EXTENSION
    string           "query"]]></sourcecode>
			<t>
			If an agent supports the query extension, it
			<bcp14>SHOULD</bcp14> reply with a list of supported extension names.
			</t>
			<sourcecode><![CDATA[
    byte             SSH_AGENT_EXTENSION_RESPONSE
    string           "query"
    string[]         supported extension types]]></sourcecode>
		</section>
	</section>
</section>

<section anchor="connecting"><name>Connecting to an Agent</name>
	<t>
	Agents are exposed to the local system using a connection-oriented
	endpoint. On Unix-like systems, it is typical to arrange for
	the agent to listen on a filesystem-based Unix domain socket.
	On Microsoft Windows, it is usual to use a Windows Named Pipe.
	Access to these endpoints <bcp14>SHOULD</bcp14> be controlled as discussed in
	<xref target="Security" />. Multiple clients may access a single
	agent by making connections to these sockets.
	</t>
	<t>
	In both cases, it is common to expose the name or address of the
	listening endpoint via an environment variable named "SSH_AUTH_SOCK".
	Clients of an agent will use this variable to locate and connect to
	the listening agent. Alternatively, agents  <bcp14>MAY</bcp14> use an implicit mechanism
	for clients to locate their endpoint, such as a default per-user
	location.
	</t>
</section>

<section anchor="fwd"><name>Forwarding Access to an Agent</name>
<t>

<!--[rfced] Please clarify how these two "using" clauses relate to the
     sentence:

Original:
The agent protocol may be forwarded over an SSH connection, using the
[RFC4254] connection protocol, allowing agent forwarding to be
requested for any session channel, using a model that is similar to
the connection protocol's support for X11 Forwarding (Section 6.3 of
[RFC4254]).

Perhaps:
Using the connection protocol described in [RFC4254], the agent
protocol may be forwarded over an SSH connection.  This allows agent
forwarding to be requested for any session channel using a model that
is similar to the connection protocol's support for X11 Forwarding
(Section 6.3 of [RFC4254]).

-->
	The agent protocol may be forwarded over an SSH connection, using the
	<xref target="RFC4254" /> connection protocol, allowing agent
	forwarding to be requested for any session channel, using a model
	that is similar to the connection protocol's support for X11 Forwarding
	(<xref target="RFC4254" section="6.3"/>).
	This feature is <bcp14>OPTIONAL</bcp14> for the SSH protocol and agent implementations.
	</t>
	<section anchor="fwdext">
	  <name>Advertising Agent Forwarding Support</name>
		<t>
		Support for agent forwarding may be advertised by an SSH
		server using the extension mechanism described in <xref target="RFC8308" /> using the name "agent-forward" in the
		SSH_MSG_EXT_INFO message.
		</t>
		<sourcecode><![CDATA[
    string           "agent-forward"
    string           "0" (version)]]></sourcecode>
		<t>
		Note that this protocol substantially predates the existence
		of the extension mechanism described in <xref target="RFC8308" />. Further note that
		several widely deployed SSH implementations that support agent
		forwarding do not advertise their ability to do so. SSH clients
		<bcp14>MAY</bcp14> opportunistically attempt to request agent forwarding in
		the absence of an advertisement (see <xref target="RFC8308" />)
		using the vendor-specific names mentioned below.
		Likewise, SSH servers <bcp14>MAY</bcp14> implement the vendor-specific names in
		addition to the one described here.
		</t>
	</section>
	<section anchor="fwdreq"><name>Requesting Agent Forwarding</name>
		<t>
		An SSH client may request agent forwarding for a
		previously opened session
		(see <xref target="RFC4254" section="6.1" />) using the
		following channel request. This request is sent after the
		channel has been opened, but before a shell, command, or
		subsystem has been executed.
		</t>
		<sourcecode><![CDATA[
    byte             SSH_MSG_CHANNEL_REQUEST
    uint32           channel_id
    string           "agent-req" or "auth-agent-req@openssh.com"
    boolean          want_reply]]></sourcecode>
		<t>
		Where "channel_id" is the identifier for an established session
		channel (as returned from a previous SSH_MSG_CHANNEL_OPEN
		request) and the "want_reply" flag indicates whether the SSH
		server should respond with a confirmation of whether the request
		was successful (as specified in
		<xref target="RFC4254" section="5.4"/>).
		</t>
		<t>
		If an SSH server accepts this request, typically it will arrange
		to make an endpoint (e.g., a listening socket) available and
		advertise this fact to the subordinate session. Most
		implementations on Unix-like systems do this by providing a
		user-private listening Unix domain socket and recording its
		location in an environment variable "SSH_AUTH_SOCK".
		</t>
		<t>
		As mentioned previously, many deployed implementations only
		support the pre-standardisation
		"auth-agent-req@openssh.com" request name. The "agent-req" name
		<bcp14>SHOULD</bcp14> only be used if support was explicitly advertised as
		per <xref target="fwdext" />.
		</t>
	</section>
	<section anchor="fwdtype"><name>Agent Connection Requests</name>
		<t>
		After an SSH client has requested that a session have agent
		forwarding enabled, the SSH server may request a
		connection to the forwarded agent. The SSH server does this by
		requesting a dedicated channel to communicate with the
		SSH client's agent.
		</t>
		<sourcecode><![CDATA[
    byte             SSH_MSG_CHANNEL_OPEN
    string           "agent-connect" or "auth-agent@openssh.com"
    uint32           channel_id
    uint32           local_window
    uint32           local_maxpacket]]></sourcecode>
		<t>
		The "channel_id", "local_window", and "local_maxpacket" fields
		should be interpreted as specified by
		<xref target="RFC4254" section="5.1"/>.
		</t>
		<t>
		As above, the "agent-connect" open type name <bcp14>SHOULD</bcp14> only be
		used if support was explicitly advertised as per
		<xref target="fwdext" />.
		</t>
		<t>
		An SSH client <bcp14>SHOULD</bcp14> be prepared to handle multiple concurrent
		forwarded connections to a client-side agent; otherwise, requests
		to access the agent from the remote side that happen to overlap
		prior requests may fail. Overlapping requests may occur because
		the SSH connection protocol <xref target="RFC4254" /> allows
		multiple user sessions over a single transport (see <xref target="RFC4253" />), which may each request use of the agentcw
		independently and potentially concurrently.
		</t>
		<t>
		An SSH client <bcp14>MAY</bcp14> accept agent connection requests (subject to
		authorisation) without a prior agent forwarding request having
		been made to support the situation where agent forwarding
		without opening a session is desired.
		Similarly, an SSH client <bcp14>MAY</bcp14> continue to accept agent connection
		requests after the session for which agent forwarding was
		requested has closed.
		</t>
		<t>
		An SSH client <bcp14>MUST</bcp14> refuse unauthorised agent connection
		requests, when agent forwarding is neither requested nor
		desired by the SSH client but an SSH server sends an agent
		connection request anyway.
		</t>
		<t>
		Because the "agent-connect" request contains no identifier to
		distinguish which session channel originated the connection
		request, an SSH connection can effectively forward
		access to only a single SSH client-side agent using
		this protocol (although there may be multiple concurrent
		connections to that single agent).
		</t>
	</section>
</section>

<section><name>Protocol Numbers</name>
	<section anchor="messagenum">
	  <name>Message Type Numbers</name>
		<t>
		The following numbers are used as message types for requests
		from the client to the agent.
		</t>
		<sourcecode><![CDATA[
    SSH_AGENTC_REQUEST_IDENTITIES                  11
    SSH_AGENTC_SIGN_REQUEST                        13
    SSH_AGENTC_ADD_IDENTITY                        17
    SSH_AGENTC_REMOVE_IDENTITY                     18
    SSH_AGENTC_REMOVE_ALL_IDENTITIES               19
    SSH_AGENTC_ADD_SMARTCARD_KEY                   20
    SSH_AGENTC_REMOVE_SMARTCARD_KEY                21
    SSH_AGENTC_LOCK                                22
    SSH_AGENTC_UNLOCK                              23
    SSH_AGENTC_ADD_ID_CONSTRAINED                  25
    SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED       26
    SSH_AGENTC_EXTENSION                           27]]></sourcecode>
		<t>
		The following numbers are used as message types for replies
		from the agent to the client.
		</t>
		<sourcecode><![CDATA[
    SSH_AGENT_FAILURE                               5
    SSH_AGENT_SUCCESS                               6
    SSH_AGENT_IDENTITIES_ANSWER                     12
    SSH_AGENT_SIGN_RESPONSE                         14
    SSH_AGENT_EXTENSION_FAILURE                     28
    SSH_AGENT_EXTENSION_RESPONSE                    29]]></sourcecode>
		<section anchor="reservednum"><name>Reserved Message Type Numbers</name>
			<t>
			The following message type numbers are reserved for
			implementations that implement support for the legacy
			SSH protocol version 1: 1-4, 7-10, 15-16, and
			24 (inclusive).
			These message numbers <bcp14>MAY</bcp14> be used by an
			implementation supporting the legacy protocol but
			<bcp14>MUST NOT</bcp14> be reused otherwise.
			</t>
			<t>
			Message number 0 is also reserved and <bcp14>MUST NOT</bcp14>
			be used.
			</t>
			<t>
			The range of message numbers 240-255 is reserved for
			Private Use extensions to the agent protocol and
			<bcp14>MUST NOT</bcp14> be used by generic implementations (see <xref target="RFC8126"/> for more information on Private Use).
			</t>
		</section>
	</section>
	<section anchor="constraintid">
	  <name>Constraint Identifiers</name>
		<t>
		The following numbers are used to identify key constraints.
		These are only used in key constraints and are not sent as
		message numbers.
		</t>
		<sourcecode><![CDATA[
    SSH_AGENT_CONSTRAIN_LIFETIME                    1
    SSH_AGENT_CONSTRAIN_CONFIRM                     2
    SSH_AGENT_CONSTRAIN_EXTENSION                   255]]></sourcecode>
		<t>
		The constraint identifier 0 is reserved.
		</t>
	</section>
	<section anchor="sigflagnum">
	  <name>Signature Flags</name>
		<t>
		The following numbers may be present in signature request
		(SSH_AGENTC_SIGN_REQUEST) messages. These flags form a bit
		field by taking the logical OR of zero or more flags.
		</t>
		<sourcecode><![CDATA[
    SSH_AGENT_RSA_SHA2_256                          0x00000002
    SSH_AGENT_RSA_SHA2_512                          0x00000004]]></sourcecode>
		<t>
		The flag value 1 is reserved for historical implementations.
		</t>
	</section>
</section>

<!--[rfced] We had the following questions related to the IANA
     registries:

a) We see no mention in the tables in this document of unassigned
values as appears at the corresponding IANA registries.

Please let us know if this document should be updated to match the
registries in this regard.

b) Please note that we have updated the column title in the Connection
Protocol Channel Types section (Table 7) to read as "Channel Type"
instead of "Request Type" to match the registry at
https://www.iana.org/assignments/ssh-parameters/ssh-parameters.xhtml#ssh-parameters-11.
Please let us know any objections.

-->

<section anchor="IANA"><name>IANA Considerations</name>
	<t>
	This protocol describes the establishment of five registries: one for
	message type numbers, one for constraint numbers,
	one for signature request
	flags, one for constraint extension names,
	and one for extension request names. Additionally,
	new codepoints are requested in three existing registries.
	</t>
	<section><name>Guidance for Designated Experts</name>
	<t>
	When a Designated Expert (DE) is asked to review additions to the
	new registries described in this document (<xref target="agentnum" />,
	<xref target="constraintnum" />, <xref target="sigflag" />, and
	<xref target="reqname" />), they are requested to verify that
	suitable documentation as described in <xref target="RFC8126" />
	exists and is permanently and publicly available.
	The DE is also requested to check the clarity of purpose and use of
	the requested codepoints. The DE should also verify that specifications
	produced in the IETF that request codepoints in these registries have
	been made available to the SSHM Working Group and the ssh@ietf.org
	mailing list for review. Requests for codepoints made for
	specifications produced outside the IETF should not conflict with
	active IETF work or prior IETF specifications.
	</t>
	<t>
	The available number of codepoints in the SSH agent protocol
	numbers (<xref target="agentnum" />), constraint numbers
	(<xref target="constraintnum" />), and SSH agent signature
	flags (<xref target="sigflag" />) registries are limited,
	so the DE is requested to ensure the use of codepoints is very well
	justified. For the SSH agent protocol message numbers, named extension
	requests (<xref target="reqname" />) provide an alternative for most
	uses with no practical limitation on the number of available codepoints.
	For key constraint numbers, the constraint extension
	mechanism (<xref target="contraintext" />) provides a similar
	alternative that is not limited by available codepoints.
	</t>
	</section>
	<section anchor="agentnum"><name>"SSH Agent Protocol Message Type Numbers" Registry</name>
		<t>
		The "SSH Agent Protocol Message Type Numbers" registry
		records the message type numbers for client requests and
		agent responses.
		It is located in the "Secure Shell (SSH) Protocol
		Parameters" registry group <xref target="IANA-SSH" />.
		Its initial state consists of the following
		numbers and reservations.
		Future message number allocations shall occur via
		Expert Review as per <xref target="RFC8126" />.
		</t>
<table>
<thead>
<tr><th>Number</th><th>Identifier</th><th>Reference</th></tr>
</thead>
<tbody>
<tr><td>0</td><td>Reserved</td><td>RFC 9987, <xref target="reservednum" /></td></tr>
<tr><td>1</td><td>Reserved</td><td>RFC 9987, <xref target="reservednum" /></td></tr>
<tr><td>2</td><td>Reserved</td><td>RFC 9987, <xref target="reservednum" /></td></tr>
<tr><td>3</td><td>Reserved</td><td>RFC 9987, <xref target="reservednum" /></td></tr>
<tr><td>4</td><td>Reserved</td><td>RFC 9987, <xref target="reservednum" /></td></tr>
<tr><td>5</td><td>SSH_AGENT_FAILURE</td><td>RFC 9987, Sections <xref target="genericresp" format="counter" /> and <xref target="messagenum" format="counter" /></td></tr>
<tr><td>6</td><td>SSH_AGENT_SUCCESS</td><td>RFC 9987, Sections <xref target="genericresp" format="counter" /> and <xref target="messagenum" format="counter" /></td></tr>
<tr><td>7</td><td>Reserved</td><td>RFC 9987, <xref target="reservednum" /></td></tr>
<tr><td>8</td><td>Reserved</td><td>RFC 9987, <xref target="reservednum" /></td></tr>
<tr><td>9</td><td>Reserved</td><td>RFC 9987, <xref target="reservednum" /></td></tr>
<tr><td>10</td><td>Reserved</td><td>RFC 9987, <xref target="reservednum" /></td></tr>
<tr><td>11</td><td>SSH_AGENTC_REQUEST_IDENTITIES</td><td>RFC 9987, Sections <xref target="listkeys" format="counter" /> and <xref target="messagenum" format="counter" /></td></tr>
<tr><td>12</td><td>SSH_AGENT_IDENTITIES_ANSWER</td><td>RFC 9987, Sections <xref target="listkeys" format="counter" /> and <xref target="messagenum" format="counter" /></td></tr>
<tr><td>13</td><td>SSH_AGENTC_SIGN_REQUEST</td><td>RFC 9987, Sections <xref target="privkeyops" format="counter" /> and <xref target="messagenum" format="counter" /></td></tr>
<tr><td>14</td><td>SSH_AGENT_SIGN_RESPONSE</td><td>RFC 9987, Sections <xref target="privkeyops" format="counter" /> and <xref target="messagenum" format="counter" /></td></tr>
<tr><td>15</td><td>Reserved</td><td>RFC 9987, <xref target="reservednum" /></td></tr>
<tr><td>16</td><td>Reserved</td><td>RFC 9987, <xref target="reservednum" /></td></tr>
<tr><td>17</td><td>SSH_AGENTC_ADD_IDENTITY</td><td>RFC 9987, Sections <xref target="addkeys" format="counter" /> and <xref target="messagenum" format="counter" /></td></tr>
<tr><td>18</td><td>SSH_AGENTC_REMOVE_IDENTITY</td><td>RFC 9987, Sections <xref target="rmkeys" format="counter" /> and <xref target="messagenum" format="counter" /></td></tr>
<tr><td>19</td><td>SSH_AGENTC_REMOVE_ALL_IDENTITIES</td><td>RFC 9987, Sections <xref target="rmkeys" format="counter" /> and <xref target="messagenum" format="counter" /></td></tr>
<tr><td>20</td><td>SSH_AGENTC_ADD_SMARTCARD_KEY</td><td>RFC 9987, Sections <xref target="addtoken" format="counter" /> and <xref target="messagenum" format="counter" /></td></tr>
<tr><td>21</td><td>SSH_AGENTC_REMOVE_SMARTCARD_KEY</td><td>RFC 9987, Sections <xref target="rmkeys" format="counter" /> and <xref target="messagenum" format="counter" /></td></tr>
<tr><td>22</td><td>SSH_AGENTC_LOCK</td><td>RFC 9987, Sections <xref target="lock" format="counter" /> and <xref target="messagenum" format="counter" /></td></tr>
<tr><td>23</td><td>SSH_AGENTC_UNLOCK</td><td>RFC 9987, Sections <xref target="lock" format="counter" /> and <xref target="messagenum" format="counter" /></td></tr>
<tr><td>24</td><td>Reserved</td><td>RFC 9987, <xref target="reservednum" /></td></tr>
<tr><td>25</td><td>SSH_AGENTC_ADD_ID_CONSTRAINED</td><td>RFC 9987, Sections <xref target="addkeys" format="counter" /> and <xref target="messagenum" format="counter" /></td></tr>
<tr><td>26</td><td>SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED</td><td>RFC 9987, Sections <xref target="addtoken" format="counter" /> and <xref target="messagenum" format="counter" /></td></tr>
<tr><td>27</td><td>SSH_AGENTC_EXTENSION</td><td>RFC 9987, Sections <xref target="extreq" format="counter" /> and <xref target="messagenum" format="counter" /></td></tr>
<tr><td>28</td><td>SSH_AGENT_EXTENSION_FAILURE</td><td>RFC 9987, Sections <xref target="extreq" format="counter" /> and <xref target="messagenum" format="counter" /></td></tr>
<tr><td>29</td><td>SSH_AGENT_EXTENSION_RESPONSE</td><td>RFC 9987, Sections <xref target="extreq" format="counter" /> and <xref target="messagenum" format="counter" /></td></tr>
<tr><td>240-255</td><td>Private Use</td><td>RFC 9987, <xref target="messagenum" /></td></tr>
</tbody>
</table>
	</section>
	<section anchor="constraintnum"><name>"SSH Agent Key Constraint Numbers" Registry</name>
		<t>
		The "SSH Agent Key Constraint Numbers" registry
		records the message numbers for key use constraints.
		It is located in the "Secure Shell (SSH) Protocol
		Parameters" registry group <xref target="IANA-SSH" />.
		Its initial state is as follows.
		Future key constraint number allocations shall occur via
		Expert Review as per <xref target="RFC8126" />.
		</t>
<table>
<thead>
<tr><th>Number</th><th>Identifier</th><th>Reference</th></tr>
</thead>
<tbody>
<tr><td>0</td><td>Reserved</td><td>RFC 9987, <xref target="constraintid" /></td></tr>
<tr><td>1</td><td>SSH_AGENT_CONSTRAIN_LIFETIME</td><td>RFC 9987, <xref target="constraintid" /></td></tr>
<tr><td>2</td><td>SSH_AGENT_CONSTRAIN_CONFIRM</td><td>RFC 9987, <xref target="constraintid" /></td></tr>
<tr><td>255</td><td>SSH_AGENT_CONSTRAIN_EXTENSION</td><td>RFC 9987, <xref target="constraintid" /></td></tr>
</tbody>
</table>
	</section>
	<section anchor="constraintexts"><name>"SSH Agent Key Constraint Extension Names" Registry</name>
		<t>
		The "SSH Agent Key Constraint Extension Names" registry
		records the names used in the SSH_AGENT_CONSTRAIN_EXTENSION
		constraint extension type (<xref target="contraintext" />).
		It is located in the "Secure Shell (SSH) Protocol
		Parameters" registry group <xref target="IANA-SSH" />.
		Its initial state is empty.
		Future key constraint extension name allocations shall occur via
		Expert Review as per <xref target="RFC8126" />.
		</t>
	</section>
	<section anchor="sigflag"><name>"SSH Agent Signature Flags" Registry</name>
		<t>
		The "SSH Agent Signature Flags" registry
		records the values for signature request
		(SSH_AGENTC_SIGN_REQUEST) flag values.
		It is located in the "Secure Shell (SSH) Protocol
		Parameters" registry group <xref target="IANA-SSH" />.
		Its initial state consists of the
		following numbers. Note that as the flags are
		combined by bitwise OR, all flag values must be
		powers of two and the maximum available
		flag value is 0x80000000.
		</t>
		<t>
		Future signature flag allocations shall occur via
		Expert Review as per <xref target="RFC8126" />.
		</t>
<table>
<thead>
<tr><th>Number</th><th>Identifier</th><th>Reference</th></tr>
</thead>
<tbody>
<tr><td>0x01</td><td>Reserved</td><td>RFC 9987, <xref target="sigflagnum" /></td></tr>
<tr><td>0x02</td><td>SSH_AGENT_RSA_SHA2_256</td><td>RFC 9987, <xref target="sigflagnum" /></td></tr>
<tr><td>0x04</td><td>SSH_AGENT_RSA_SHA2_512</td><td>RFC 9987, <xref target="sigflagnum" /></td></tr>
</tbody>
</table>
	</section>
	<section anchor="reqname"><name>"SSH Agent Extension Request Names" Registry</name>
		<t>
		The "SSH Agent Extension Request Names" registry
		records the names used in the generic extension request
		message (SSH_AGENTC_EXTENSION).
		It is located in the "Secure Shell (SSH) Protocol
		Parameters" registry group <xref target="IANA-SSH" />.
		Its initial state consists of the
		following names.
		</t>
		<t>
		Future name allocations shall occur via
		Expert Review as per <xref target="RFC8126" />.
		</t>
<table>
<thead>
<tr><th>Extension Name</th><th>Reference</th></tr>
</thead>
<tbody>
<tr><td>query</td><td>RFC 9987, <xref target="queryext" /></td></tr>
</tbody>
</table>
	</section>
	<section>
	  <name>Additions to the "Extension Names" Registry</name>
		<t>
		IANA has added the following entries to the
		"Extension Names" registry <xref target="IANA-SSH-EXT" /> in
		the "Secure Shell (SSH) Protocol Parameters" registry group
		<xref target="IANA-SSH" />.
		</t>
<table>
<thead>
<tr><th>Extension Name</th><th>Reference</th></tr>
</thead>
<tbody>
<tr><td>agent-forward</td><td>RFC 9987, <xref target="fwdext" /></td></tr>
</tbody>
</table>
	</section>
	<section>
	  <name>Additions to the "Connection Protocol Channel Request Names" Registry</name>
		<t>
		IANA has added the following entries to the
		"Connection Protocol Channel Request Names" registry
		<xref target="IANA-SSH-CHANREQ" /> in the
		"Secure Shell (SSH) Protocol Parameters" registry group
		<xref target="IANA-SSH" />.
		</t>
<table>
<thead>
<tr><th>Request Type</th><th>Reference</th></tr>
</thead>
<tbody>
<tr><td>agent-req</td><td>RFC 9987, <xref target="fwdreq" /></td></tr>
</tbody>
</table>
	</section>
	<section>
	  <name>Additions to the "Connection Protocol Channel Types" Registry</name>
		<t>
		IANA has added the following entries to the
		"Connection Protocol Channel Types" registry <xref target="IANA-SSH-CHANTYPE" /> under the
		"Secure Shell (SSH) Protocol Parameters" registry group
		<xref target="IANA-SSH" />.
		</t>
<table>
<thead>
<tr><th>Channel Type</th><th>Reference</th></tr>
</thead>
<tbody>
<tr><td>agent-connect</td><td>RFC 9987, <xref target="fwdtype" /></td></tr>
</tbody>
</table>
	</section>
</section>

<section anchor="Security"><name>Security Considerations</name>
	<t>
	The agent is a service that is tasked with retaining and providing
	controlled access to what are typically long-lived login
	authentication credentials. It is, by nature, a sensitive and trusted
	software component. Moreover, the agent protocol itself does not
	include any authentication or transport security; ability to
	communicate with an agent is usually sufficient to invoke it to
	perform private key operations.
	</t>
	<t>
	Since being able to access an agent is usually sufficient to perform
	private key operations, it is critically important that the agent
	only be exposed to its owner and their authorised delegates.
	On Unix-like systems, this may be achieved via filesystem permissions
	on the agent socket and/or identity checks on the client connected
	to a socket (e.g., SO_PEERCRED on some Unix-like systems).
	On Windows, access to a named pipe may be controlled by attaching a
	security descriptor at the time of its creation.
	</t>
	<t>
	The primary design intention of an agent is that an attacker with
	unprivileged access to their victim's agent should be prevented from
	gaining a copy of any keys that have been loaded into it. This may
	not preclude the attacker from stealing use of those keys (e.g.,
	if they have been loaded without a confirmation constraint).
	</t>
	<t>
	Given this, the agent should, as far as possible, prevent its
	memory from being read by other processes to prevent theft of loaded keys.
	Typically, this includes disabling debugging interfaces and
	preventing process memory dumps on abnormal termination.
	</t>
	<t>
	Another, more subtle, means by which keys may be stolen is via
	cryptographic side-channels. Private key operations may leak
	information about the contents of keys via differences in timing,
	power use, or by side effects in the memory subsystems (e.g., CPU
	caches) of the host running the agent. For the case of a local
	attacker and an agent holding unconstrained keys, the only limit
	on the number of private key operations the attacker may be able
	to observe is the rate at which the CPU can perform signatures.
	This grants the attacker an almost ideal oracle for side-channel
	attacks.  While a full treatment of side-channel attacks is beyond
	the scope of this specification, agents <bcp14>SHOULD</bcp14> use cryptographic
	implementations that are resistant to side-channel attacks and <bcp14>MAY</bcp14>
	take additional measures to hide the actual time spent processing
	private key operations. Failure to do so may expose keys to recovery
	through these side-channels.
	</t>
	<t>
	Forwarding access to a local agent over an SSH connection
	(<xref target="fwd" />) inherently creates a transitive trust
	relationship. SSH implementations <bcp14>SHOULD NOT</bcp14> forward use of an agent
	by default, and users <bcp14>SHOULD NOT</bcp14> forward use of an agent to hosts that
	are not fully trusted, as doing so could expose access to the user's
	keys to attackers on remote hosts. Agents <bcp14>SHOULD</bcp14> implement additional
	controls over key visibility and use for forwarded agent connections;
	otherwise, the user has only an all-or-nothing choice about whether to
	forward an agent.
	</t>

<!--[rfced] How would we separate this slashed phrase?

Original:
Implementation of token/smartcard-hosted keys...

Perhaps A:

Implementation of keys hosted by a token or smartcard....

Perhaps B:
Implementation of token keys or smartcard-hosted keys...
-->

	
	<t>
	Implementation of token/smartcard-hosted keys requires some care, too.
	On some systems, tokens may be invoked by providing a path to a shared
	library that must be loaded to make use of keys hosted on the device
	(a path to a library for a particular PKCS#11 module, for example).
	Loading a shared library on most platforms implies automatic
	execution of code in that library in the address space of
	the process that loads it.
	To avoid the loading of potentially hostile code, agents that support
	loading token-hosted keys via a  library path <bcp14>SHOULD</bcp14> ensure that only
	trusted token provider libraries are loadable.
	Additionally, agents <bcp14>SHOULD</bcp14> ensure that loaded token library code
	cannot gain access to other keys loaded in the agent and <bcp14>MAY</bcp14> disallow
	remote clients from loading token keys entirely.
	Protection for existing keys from a token library code may be achieved
	by loading the token library into a separate process to the agent
	and arranging for the agent to invoke token operations to this
	process via IPC.
	</t>
	<t>
	Finally, with respect to the agent locking functionality in
	<xref target="lock" />, an agent <bcp14>SHOULD</bcp14> take countermeasures
	against brute-force guessing attacks on the passphrase.
	This may take the form of enforced delays when an unlock attempt is
	made with an incorrect password (potentially increasing for subsequent
	failures), a lockout period where the agent refuses to accept further
	requests after some threshold of failed unlock attempts has been made,
	and/or deletion of all keys held by the agent after a threshold of
	failed unlock attempts.
	</t>
</section>

</middle>

<back>
<references>
	<name>References</name>
	<references><name>Normative References</name>
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4251.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4253.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4254.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5656.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8032.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8308.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8332.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8709.xml" />

                <reference anchor="FIPS.186-4">
                  <front>
                    <title>Digital Signature Standard (DSS)</title>
                    <author>
                      <organization abbrev="NIST">National Institute of Standards and Technology</organization>
                    </author>
                    <date month="June" year="2013"/>
                  </front>
                  <seriesInfo name="NIST FIPS" value="186-4"/>
                  <seriesInfo name="DOI" value="10.6028/NIST.FIPS.186-4"/>
                </reference>

                <reference anchor="FIPS.186-5">
                  <front>
                    <title>Digital Signature Standard (DSS)</title>
                    <author>
                      <organization abbrev="NIST">National Institute of Standards and Technology</organization>
                    </author>
                    <date month="February" year="2023"/>
                  </front>
                  <seriesInfo name="NIST FIPS" value="186-5"/>
                  <seriesInfo name="DOI" value="10.6028/NIST.FIPS.186-5"/>
                </reference>
	</references>

	<references><name>Informative References</name>
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4252.xml" />
		<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8126.xml" />
		<reference anchor="IANA-SSH-CHANREQ" target="https://www.iana.org/assignments/ssh-parameters/"><front>
			<title>Connection Protocol Channel Types</title>
			<author>
				<organization>IANA</organization>
			</author>
		</front></reference>
		<reference anchor="IANA-SSH" target="https://www.iana.org/assignments/ssh-parameters/"><front>
			<title>Secure Shell (SSH) Protocol Parameters</title>
			<author>
				<organization>IANA</organization>
			</author>
		</front></reference>
		<reference anchor="IANA-SSH-CHANTYPE" target="https://www.iana.org/assignments/ssh-parameters/"><front>
			<title>Extension Names</title>
			<author>
				<organization>IANA</organization>
			</author>
		</front></reference>
		<reference anchor="IANA-SSH-EXT" target="https://www.iana.org/assignments/ssh-parameters/"><front>
			<title>Connection Protocol Channel Request Names</title>
			<author>
				<organization>IANA</organization>
			</author>
		</front></reference>
		<reference anchor="IANA-PUBKEYS" target="https://www.iana.org/assignments/ssh-parameters/"><front>
			<title>Public Key Algorithm Names</title>
			<author>
				<organization>IANA</organization>
			</author>
		</front></reference>

<!-- [rfced] Note that the reference [I-D.ietf-secsh-agent] has been
     removed as it had no corresponding citation in the document.
     Please let us know any objections.
                -->

	</references>
</references>

<section anchor="Acknowledgments" numbered="false"><name>Acknowledgments</name>
	<t>
	This protocol was designed and first implemented by
	<contact fullname="Markus Friedl"/>, based on a similar protocol for an agent
	to support the legacy SSH version 1 by <contact fullname="Tatu Ylonen"/>.
	</t>
	<t>
	Thanks to <contact fullname="Simon Tatham"/>, <contact fullname="Niels
	Möller"/>, <contact fullname="James Spencer"/>, <contact
	fullname="Simon Josefsson"/>, <contact fullname="Matt Johnston"/>,
	<contact fullname="Jakub Jelen"/>, <contact fullname="Rich Salz"/>,
	<contact fullname="Caspar Schutijser"/>, <contact fullname="Florian
	Obser"/>, <contact fullname="Martin Thomson"/>, <contact fullname="Deb
	Cooley"/>, and <contact fullname="Tero Kivinen"/> who reviewed and
	helped improve this document.
	</t>
</section>

<!-- [rfced] Would you like the references to be alphabetized or left
     in their current order?
-->

<!--[rfced] Please note that we have expanded abbreviations on first
     use.  Please review these expansions for accuracy. -->

<!-- [rfced] We had the following questions/comments regarding
     responses from the document intake email:

a) Regarding <sourcecode>:

"This document has none of the former, but plenty of the latter. The
stuff in <sourcecode> blocks are message definitions. Did I use the
wrong element type?"

None of the <sourcecode> pieces have a type set.  The only type with
"message" in the name at the list (see below) is "http-message".

Please let us know if you would like to set a <sourcecode> type for
each instance of the sourcecode element.  If the current list of
preferred values for "type"
(https://www.rfc-editor.org/rpc/wiki/doku.php?id=sourcecode-types)
does not contain an applicable type, then feel free to let us know.

Also, it is acceptable to leave the "type" attribute not set.  Please
let us know if that is your choice.

b) Regarding using quotes for protocol message field names and literal
strings:

"Literal strings that appear in protocol messages should be in double
quotes both in protocol message definitions and in descriptive text.

Protocol message field names should be in double quotes when they
appear in descriptive text, but not in the protocol message
definition."

It seemed the byte names (e.g., SSH_AGENTC_ADD_ID_CONSTRAINED) were
never in quotes.  We have left these as they were.

Please review our updates and let us know if any further changes are
necessary (as these same terms seem to be used in the general sense,
this was not always clear to us).

 -->

<!--[rfced] We had the following questions/comments related to
    terminology use throughout the document:

a) Should the use of "type" and "key type" be made uniform here?

type "ssh-dss" vs. key type "ssh-rsa"

b) We see both "Windows Named Pipe" and "On Windows, access to a named
pipe".  Please review and let us know if updates should be made for
uniformity.
-->

<!-- [rfced] Please review the "Inclusive Language" portion of the
     online Style Guide
     <https://www.rfc-editor.org/styleguide/part2/#inclusive_language>
     and let us know if any changes are needed.  Updates of this
     nature typically result in more precise language, which is
     helpful for readers.

Note that our script did not flag any words in particular, but this
should still be reviewed as a best practice.

-->


</back>
</rfc>
