Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,16 @@ curl -I -L --fail https://github.com/minekube/connect-java/releases/download/<ve
`NmsDiagnostics` helpers so they stay reportable; `spigot/.../util/NmsDiagnosticsTest`
guards this contract.

## Bedrock signed-principal v2

- Operator behavior and configuration belong in `docs/bedrock-identity.md`. Authoritative Java
surfaces are `api/.../player/principal`, `core/.../bedrock/BedrockPrincipalConsumer`, the
Watch/libp2p protos and registration framing, and
`core/src/test/resources/bedrock-principal-v2/UPSTREAM`.
- Keep principals verifier-constructed/sealed, consume envelopes only from authenticated wire
field 12, preserve generation-1 `warn` files byte-for-byte, and never advertise v2 readiness
without exact generation-2 `require`, usable keys, replay, and profile application.

## Java runtime compatibility

- Java 26 is not a libp2p classloader incompatibility; the isolation has been verified on
Expand Down
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,8 @@ integration contract and its permanent-stability commitment.

## Bedrock identity verification

New installations trust Connect Edge's signed Bedrock identities in non-rejecting `warn` mode
without requiring operators to paste key configuration. See
[docs/bedrock-identity.md](docs/bedrock-identity.md) for the trust boundary, Java-only behavior,
and static-key pinning.
See [docs/bedrock-identity.md](docs/bedrock-identity.md) for legacy v1 behavior, signed-principal
v2 configuration, the trust boundary, and static-key pinning.

## Connect libp2p endpoint mode

Expand Down
9 changes: 9 additions & 0 deletions api/src/main/java/com/minekube/connect/api/ConnectApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import com.minekube.connect.api.player.ConnectPlayer;
import com.minekube.connect.api.player.bedrock.BedrockIdentityClaims;
import com.minekube.connect.api.player.principal.VerifiedBedrockPrincipal;
import java.util.Collection;
import java.util.Optional;
import java.util.UUID;
Expand Down Expand Up @@ -77,4 +78,12 @@ static ConnectApi getInstance() {
default Optional<BedrockIdentityClaims> getVerifiedBedrockIdentity(ConnectPlayer player) {
return Optional.empty();
}

/**
* Returns the verifier-created v2 Bedrock principal for this player's current session.
* Callers must not log or serialize identity/link accessors.
*/
default Optional<VerifiedBedrockPrincipal> getVerifiedBedrockPrincipal(ConnectPlayer player) {
return Optional.empty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
public final class BedrockIdentityProfiles {
/** Private transport property carrying endpoint and organization scope for legacy Watch. */
public static final String SCOPE_PROPERTY_NAME = "minekube:bedrock_identity_scope";
/** Reserved property name: v2 is accepted only from authenticated wire field 12. */
public static final String PRINCIPAL_V2_PROPERTY_NAME = "minekube:bedrock_principal_v2";

private BedrockIdentityProfiles() {
}
Expand Down Expand Up @@ -42,6 +44,7 @@ public static GameProfile withoutEnvelope(GameProfile profile) {
*/
public static boolean isPublic(GameProfile.Property property) {
return !BedrockIdentityVerifier.PROPERTY_NAME.equals(property.getName()) &&
!SCOPE_PROPERTY_NAME.equals(property.getName());
!SCOPE_PROPERTY_NAME.equals(property.getName()) &&
!PRINCIPAL_V2_PROPERTY_NAME.equals(property.getName());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.minekube.connect.api.player.principal;

/** Strict Bedrock signed-principal v2 verifier. */
public interface BedrockPrincipalVerifier {
VerifiedBedrockPrincipal verifyAndConsume(
SignedPrincipalEnvelope envelope,
TrustedProposalContext expected) throws PrincipalVerificationException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.minekube.connect.api.player.principal;

import java.util.Objects;

/** The sole public construction entry point for a Bedrock principal verifier. */
public final class BedrockPrincipalVerifierFactory {
private BedrockPrincipalVerifierFactory() {}

public static BedrockPrincipalVerifier create(VerifierConfiguration configuration) {
return new DefaultBedrockPrincipalVerifier(
Objects.requireNonNull(configuration, "configuration"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.minekube.connect.api.player.principal;

import java.util.Objects;

/** A canonical positive decimal XUID verified by the SDK. */
public final class CanonicalXuid {
private final transient String value;

CanonicalXuid(String value) {
this.value = Objects.requireNonNull(value, "value");
}

public String value() {
return value;
}

@Override
public boolean equals(Object other) {
return other instanceof CanonicalXuid && value.equals(((CanonicalXuid) other).value);
}

@Override
public int hashCode() {
return value.hashCode();
}

@Override
public String toString() {
return "CanonicalXuid[redacted]";
}
}
Loading
Loading