diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 87ce2b0c1b31b5d43b9107bf8b2614438865ce4b..3475e80b795d39b0ce0fa1af9bcbd298ac8a1705 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -1418,16 +1418,95 @@ void ast_sip_session_unsuspend(struct ast_sip_session *session)
 	ao2_ref(suspender, -1);
 }
 
-static int session_outbound_auth(pjsip_dialog *dlg, pjsip_tx_data *tdata, void *user_data)
+/*!
+ * \internal
+ * \brief Handle initial INVITE challenge response message.
+ * \since 13.5.0
+ *
+ * \param rdata PJSIP receive response message data.
+ *
+ * \retval PJ_FALSE Did not handle message.
+ * \retval PJ_TRUE Handled message.
+ */
+static pj_bool_t outbound_invite_auth(pjsip_rx_data *rdata)
 {
-	pjsip_inv_session *inv = pjsip_dlg_get_inv_session(dlg);
-	struct ast_sip_session *session = inv->mod_data[session_module.id];
+	pjsip_transaction *tsx;
+	pjsip_dialog *dlg;
+	pjsip_inv_session *inv;
+	pjsip_tx_data *tdata;
+	struct ast_sip_session *session;
+
+	if (rdata->msg_info.msg->line.status.code != 401
+		&& rdata->msg_info.msg->line.status.code != 407) {
+		/* Doesn't pertain to us. Move on */
+		return PJ_FALSE;
+	}
+
+	tsx = pjsip_rdata_get_tsx(rdata);
+	dlg = pjsip_rdata_get_dlg(rdata);
+	if (!dlg || !tsx) {
+		return PJ_FALSE;
+	}
 
-	if (inv->state < PJSIP_INV_STATE_CONFIRMED && tdata->msg->line.req.method.id == PJSIP_INVITE_METHOD) {
-		pjsip_inv_uac_restart(inv, PJ_FALSE);
+	if (tsx->method.id != PJSIP_INVITE_METHOD) {
+		/* Not an INVITE that needs authentication */
+		return PJ_FALSE;
+	}
+
+	inv = pjsip_dlg_get_inv_session(dlg);
+	if (PJSIP_INV_STATE_CONFIRMED <= inv->state) {
+		/*
+		 * We cannot handle reINVITE authentication at this
+		 * time because the reINVITE transaction is still in
+		 * progress.
+		 */
+		ast_debug(1, "A reINVITE is being challenged.\n");
+		return PJ_FALSE;
 	}
+	ast_debug(1, "Initial INVITE is being challenged.\n");
+
+	session = inv->mod_data[session_module.id];
+
+	if (ast_sip_create_request_with_auth(&session->endpoint->outbound_auths, rdata, tsx,
+		&tdata)) {
+		return PJ_FALSE;
+	}
+
+	/*
+	 * Restart the outgoing initial INVITE transaction to deal
+	 * with authentication.
+	 */
+	pjsip_inv_uac_restart(inv, PJ_FALSE);
+
 	ast_sip_session_send_request(session, tdata);
-	return 0;
+	return PJ_TRUE;
+}
+
+static pjsip_module outbound_invite_auth_module = {
+	.name = {"Outbound INVITE Auth", 20},
+	.priority = PJSIP_MOD_PRIORITY_DIALOG_USAGE,
+	.on_rx_response = outbound_invite_auth,
+};
+
+/*!
+ * \internal
+ * \brief Setup outbound initial INVITE authentication.
+ * \since 13.5.0
+ *
+ * \param dlg PJSIP dialog to attach outbound authentication.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int setup_outbound_invite_auth(pjsip_dialog *dlg)
+{
+	pj_status_t status;
+
+	++dlg->sess_count;
+	status = pjsip_dlg_add_usage(dlg, &outbound_invite_auth_module, NULL);
+	--dlg->sess_count;
+
+	return status != PJ_SUCCESS ? -1 : 0;
 }
 
 struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint,
@@ -1465,7 +1544,7 @@ struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint
 		return NULL;
 	}
 
-	if (ast_sip_dialog_setup_outbound_authentication(dlg, endpoint, session_outbound_auth, NULL)) {
+	if (setup_outbound_invite_auth(dlg)) {
 		pjsip_dlg_terminate(dlg);
 		return NULL;
 	}
@@ -1505,7 +1584,7 @@ struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint
 		ao2_cleanup(joint_caps);
 	}
 
-	if ((pjsip_dlg_add_usage(dlg, &session_module, NULL) != PJ_SUCCESS)) {
+	if (pjsip_dlg_add_usage(dlg, &session_module, NULL) != PJ_SUCCESS) {
 		pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
 		/* Since we are not notifying ourselves that the INVITE session is being terminated
 		 * we need to manually drop its reference to session
@@ -2254,6 +2333,7 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans
 {
 	ast_sip_session_response_cb cb;
 	struct ast_sip_session *session = inv->mod_data[session_module.id];
+	pjsip_tx_data *tdata;
 
 	print_debug_details(inv, tsx, e);
 	if (!session) {
@@ -2283,12 +2363,23 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans
 					if (tsx->status_code == PJSIP_SC_REQUEST_PENDING) {
 						reschedule_reinvite(session, cb);
 						return;
-					} else if (inv->state == PJSIP_INV_STATE_CONFIRMED &&
-						   tsx->status_code != 488) {
-						/* Other reinvite failures (except 488) result in destroying the session. */
-						pjsip_tx_data *tdata;
-						if (pjsip_inv_end_session(inv, 500, NULL, &tdata) == PJ_SUCCESS) {
-							ast_sip_session_send_request(session, tdata);
+					}
+					if (inv->state == PJSIP_INV_STATE_CONFIRMED) {
+						ast_debug(1, "reINVITE received final response code %d\n",
+							tsx->status_code);
+						if ((tsx->status_code == 401 || tsx->status_code == 407)
+							&& !ast_sip_create_request_with_auth(
+								&session->endpoint->outbound_auths,
+								e->body.tsx_state.src.rdata, tsx, &tdata)) {
+							/* Send authed reINVITE */
+							ast_sip_session_send_request_with_cb(session, tdata, cb);
+							return;
+						}
+						if (tsx->status_code != 488) {
+							/* Other reinvite failures (except 488) result in destroying the session. */
+							if (pjsip_inv_end_session(inv, 500, NULL, &tdata) == PJ_SUCCESS) {
+								ast_sip_session_send_request(session, tdata);
+							}
 						}
 					}
 				} else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
@@ -2299,14 +2390,30 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans
 						 * a cancelled call. Our role is to immediately send a BYE to end the
 						 * dialog.
 						 */
-						pjsip_tx_data *tdata;
-
 						if (pjsip_inv_end_session(inv, 500, NULL, &tdata) == PJ_SUCCESS) {
 							ast_sip_session_send_request(session, tdata);
 						}
 					}
 				}
 			}
+		} else {
+			/* All other methods */
+			if (tsx->role == PJSIP_ROLE_UAC) {
+				if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {
+					/* This means we got a final response to our outgoing method */
+					ast_debug(1, "%.*s received final response code %d\n",
+						(int) pj_strlen(&tsx->method.name), pj_strbuf(&tsx->method.name),
+						tsx->status_code);
+					if ((tsx->status_code == 401 || tsx->status_code == 407)
+						&& !ast_sip_create_request_with_auth(
+							&session->endpoint->outbound_auths,
+							e->body.tsx_state.src.rdata, tsx, &tdata)) {
+						/* Send authed version of the method */
+						ast_sip_session_send_request_with_cb(session, tdata, cb);
+						return;
+					}
+				}
+			}
 		}
 		if (cb) {
 			cb(session, e->body.tsx_state.src.rdata);
@@ -2640,6 +2747,7 @@ static int load_module(void)
 		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_sip_register_service(&session_reinvite_module);
+	ast_sip_register_service(&outbound_invite_auth_module);
 
 	ast_module_shutdown_ref(ast_module_info->self);
 
@@ -2648,6 +2756,7 @@ static int load_module(void)
 
 static int unload_module(void)
 {
+	ast_sip_unregister_service(&outbound_invite_auth_module);
 	ast_sip_unregister_service(&session_reinvite_module);
 	ast_sip_unregister_service(&session_module);
 	ast_sorcery_delete(ast_sip_get_sorcery(), nat_hook);