diff --git a/doc/man/knot.conf.5in b/doc/man/knot.conf.5in
index 6682e0b4b5feac0ab201899460eb1f8c3d948c48..92f6b294010508de61d162a496a4e03df28c949c 100644
--- a/doc/man/knot.conf.5in
+++ b/doc/man/knot.conf.5in
@@ -455,7 +455,7 @@ the signal parameters are \fIzone name\fP and \fIzone SOA serial\fP\&.
 .IP \(bu 2
 \fBksk\-submission\fP – The signal \fBzone_ksk_submission\fP is emitted if there is
 a ready KSK present when the zone is signed; the signal parameters are
-\fIzone name\fP and \fIKSK keytag\fP\&.
+\fIzone name\fP, \fIKSK keytag\fP, and \fIKSK KASP id\fP\&.
 .UNINDENT
 .sp
 \fBNOTE:\fP
diff --git a/doc/reference.rst b/doc/reference.rst
index 9c4f78cefce2710312526ef510d8f6edd5149578..0d623480cdedce097878f61a00eb28d90aa3feef 100644
--- a/doc/reference.rst
+++ b/doc/reference.rst
@@ -483,7 +483,7 @@ Possible values:
   the signal parameters are `zone name` and `zone SOA serial`.
 - ``ksk-submission`` – The signal ``zone_ksk_submission`` is emitted if there is
   a ready KSK present when the zone is signed; the signal parameters are
-  `zone name` and `KSK keytag`.
+  `zone name`, `KSK keytag`, and `KSK KASP id`.
 
 .. NOTE::
    This function requires systemd version at least 221.
diff --git a/src/knot/common/systemd.c b/src/knot/common/systemd.c
index 1e1079845e748c96ee6c5656c11bdee0d01c9420..c7d1ebcdb67b5ffc6c0598e360417aa15e98249e 100644
--- a/src/knot/common/systemd.c
+++ b/src/knot/common/systemd.c
@@ -144,13 +144,14 @@ void systemd_emit_zone_updated(const knot_dname_t *zone_name, uint32_t serial)
 #endif
 }
 
-void systemd_emit_zone_submission(const knot_dname_t *zone_name, uint16_t keytag)
+void systemd_emit_zone_submission(const knot_dname_t *zone_name, uint16_t keytag,
+                                  const char *keyid)
 {
 #ifdef ENABLE_DBUS
 	knot_dname_txt_storage_t buff;
 	char *zone_str = knot_dname_to_str(buff, zone_name, sizeof(buff));
 	if (zone_str != NULL) {
-		emit_event(KNOT_BUS_EVENT_ZONE_KSK_SUBM, "sq", zone_str, keytag);
+		emit_event(KNOT_BUS_EVENT_ZONE_KSK_SUBM, "sqs", zone_str, keytag, keyid);
 	}
 #endif
 }
diff --git a/src/knot/common/systemd.h b/src/knot/common/systemd.h
index 3b2ef82eabef31fafb1a206e5cf5510a0b4c849a..a1cac84a87a88d792a38705181de44b1e31216eb 100644
--- a/src/knot/common/systemd.h
+++ b/src/knot/common/systemd.h
@@ -91,5 +91,7 @@ void systemd_emit_zone_updated(const knot_dname_t *zone_name, uint32_t serial);
  *
  * \param zone_name  Zone name.
  * \param keytag     Keytag of the ready key.
+ * \param keyid      KASP id of the ready key.
  */
-void systemd_emit_zone_submission(const knot_dname_t *zone_name, uint16_t keytag);
+void systemd_emit_zone_submission(const knot_dname_t *zone_name, uint16_t keytag,
+                                  const char *keyid);
diff --git a/src/knot/dnssec/key-events.c b/src/knot/dnssec/key-events.c
index c200f8e341cd8303395d69997b5e89192f5b1853..018cbacb8a68bf93ffff19f65d65b76b90ddad54 100644
--- a/src/knot/dnssec/key-events.c
+++ b/src/knot/dnssec/key-events.c
@@ -263,7 +263,7 @@ typedef struct {
 	bool ksk;
 	knot_time_t time;
 	knot_kasp_key_t *key;
-	int ready_key;
+	const knot_kasp_key_t *ready_key;
 } roll_action_t;
 
 static const char *roll_action_name(roll_action_type_t type)
@@ -384,7 +384,7 @@ static knot_time_t alg_remove_time(knot_time_t post_active_time, const kdnssec_c
 static roll_action_t next_action(kdnssec_ctx_t *ctx, zone_sign_roll_flags_t flags)
 {
 	roll_action_t res = { 0 };
-	res.ready_key = -1;
+	res.ready_key = NULL;
 
 	for (size_t i = 0; i < ctx->zone->num_keys; i++) {
 		knot_kasp_key_t *key = &ctx->zone->keys[i];
@@ -408,7 +408,7 @@ static roll_action_t next_action(kdnssec_ctx_t *ctx, zone_sign_roll_flags_t flag
 			case DNSSEC_KEY_STATE_READY:
 				keytime = ksk_sbm_max_time(key->timing.ready, ctx);
 				restype = REPLACE;
-				res.ready_key = dnssec_key_get_keytag(key->key);
+				res.ready_key = key;
 				break;
 			case DNSSEC_KEY_STATE_ACTIVE:
 				if (!running_rollover(ctx) &&
@@ -623,7 +623,7 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_roll_flags_t flags,
 		return KNOT_EOK;
 	}
 	int ret = KNOT_EOK;
-	uint16_t plan_ds_keytag = 0;
+	const knot_kasp_key_t *ready_key = NULL;
 	bool allowed_general_roll = ((flags & KEY_ROLL_ALLOW_KSK_ROLL) && (flags & KEY_ROLL_ALLOW_ZSK_ROLL));
 	// generate initial keys if missing
 	if (!key_present(ctx, true, false) && !key_present(ctx, true, true)) {
@@ -635,7 +635,7 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_roll_flags_t flags,
 			}
 			if (ret == KNOT_EOK) {
 				reschedule->plan_ds_check = true;
-				plan_ds_keytag = dnssec_key_get_keytag(ctx->zone->keys[0].key);
+				ready_key = &ctx->zone->keys[0];
 			}
 		}
 		if (ret == KNOT_EOK && (flags & KEY_ROLL_ALLOW_ZSK_ROLL)) {
@@ -728,7 +728,7 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_roll_flags_t flags,
 			ret = submit_key(ctx, next.key);
 			if (ret == KNOT_EOK) {
 				reschedule->plan_ds_check = true;
-				plan_ds_keytag = dnssec_key_get_keytag(next.key->key);
+				ready_key = next.key;
 			}
 			break;
 		case REPLACE:
@@ -764,10 +764,10 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_roll_flags_t flags,
 		}
 	}
 
-	if (ret == KNOT_EOK && next.ready_key >= 0) {
+	if (ret == KNOT_EOK && next.ready_key != NULL) {
 		// just to make sure DS check is scheduled
 		reschedule->plan_ds_check = true;
-		plan_ds_keytag = next.ready_key;
+		ready_key = next.ready_key;
 	}
 
 	if (ret == KNOT_EOK && knot_time_cmp(reschedule->next_rollover, ctx->now) <= 0) {
@@ -779,12 +779,13 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, zone_sign_roll_flags_t flags,
 	}
 
 	if (ret == KNOT_EOK && reschedule->plan_ds_check) {
+		uint16_t keytag = dnssec_key_get_keytag(ready_key->key);
 		char param[32];
-		(void)snprintf(param, sizeof(param), "KEY_SUBMISSION=%hu", plan_ds_keytag);
+		(void)snprintf(param, sizeof(param), "KEY_SUBMISSION=%hu", keytag);
 		log_fmt_zone(LOG_NOTICE, LOG_SOURCE_ZONE, ctx->zone->dname, param,
 		             "DNSSEC, KSK submission, waiting for confirmation");
 		if (ctx->dbus_event & DBUS_EVENT_ZONE_SUBMISSION) {
-			systemd_emit_zone_submission(ctx->zone->dname, plan_ds_keytag);
+			systemd_emit_zone_submission(ctx->zone->dname, keytag, ready_key->id);
 		}
 	}