diff --git a/LayoutTests/http/tests/identity/allow-attribute.https-expected.txt b/LayoutTests/http/tests/identity/allow-attribute.https-expected.txt
new file mode 100644
index 0000000000000..29967b1b6e95b
--- /dev/null
+++ b/LayoutTests/http/tests/identity/allow-attribute.https-expected.txt
@@ -0,0 +1,13 @@
+PASS is allowed to call get()
+PASS is not allowed to call get()
+PASS is allowed to call get()
+PASS is allowed to call get()
+PASS is allowed to call get()
+PASS is allowed to call get()
+PASS is not allowed to call get()
+PASS is not allowed to call get()
+PASS is not allowed to call get()
+PASS is allowed to call get()
+PASS is allowed to call get()
+PASS is not allowed to call get()
+
diff --git a/LayoutTests/http/tests/identity/allow-attribute.https.html b/LayoutTests/http/tests/identity/allow-attribute.https.html
new file mode 100644
index 0000000000000..183d6b6769915
--- /dev/null
+++ b/LayoutTests/http/tests/identity/allow-attribute.https.html
@@ -0,0 +1,133 @@
+
+
+
+
+ Test allow attribute with "digital-credentials-get" and
+ CredentialsContainer's .get() method
+
+
+
+
+
+
diff --git a/LayoutTests/http/tests/identity/resources/iframe.html b/LayoutTests/http/tests/identity/resources/iframe.html
new file mode 100644
index 0000000000000..398f9ac4e7603
--- /dev/null
+++ b/LayoutTests/http/tests/identity/resources/iframe.html
@@ -0,0 +1,33 @@
+
+
+
+Digital Credentials API
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/default-permissions-policy.https.sub-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/default-permissions-policy.https.sub-expected.txt
new file mode 100644
index 0000000000000..4eb103f9c0c3f
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/default-permissions-policy.https.sub-expected.txt
@@ -0,0 +1,3 @@
+
+PASS Permissions-Policy is by default 'self'.
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/default-permissions-policy.https.sub.html b/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/default-permissions-policy.https.sub.html
new file mode 100644
index 0000000000000..34a40bdcfe746
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/default-permissions-policy.https.sub.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/disabled-by-permissions-policy.https.sub-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/disabled-by-permissions-policy.https.sub-expected.txt
new file mode 100644
index 0000000000000..00b1a0529ecd6
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/disabled-by-permissions-policy.https.sub-expected.txt
@@ -0,0 +1,6 @@
+
+
+FAIL Permissions-Policy header digital-credentials-get=() disallows the top-level document. promise_rejects_dom: function "function() { throw e }" threw object "TypeError: At least one provider must be specified." that is not a DOMException NotAllowedError: property "code" is equal to undefined, expected 0
+FAIL Permissions-Policy header digital-credentials-get=() disallows same-origin iframes. assert_false: Digital Credential API expected false got true
+PASS Overridden in cross-origin iframes.
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/disabled-by-permissions-policy.https.sub.html b/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/disabled-by-permissions-policy.https.sub.html
new file mode 100644
index 0000000000000..3c0e7b0242196
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/disabled-by-permissions-policy.https.sub.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/disabled-by-permissions-policy.https.sub.html.headers b/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/disabled-by-permissions-policy.https.sub.html.headers
new file mode 100644
index 0000000000000..02a76b7c3f289
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/disabled-by-permissions-policy.https.sub.html.headers
@@ -0,0 +1 @@
+Permissions-Policy: digital-credentials-get=()
diff --git a/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub-expected.txt
new file mode 100644
index 0000000000000..bcf510af6b98c
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub-expected.txt
@@ -0,0 +1,6 @@
+
+PASS Permissions-Policy header digital-credentials-get=(self) allows the top-level document.
+PASS Permissions-Policy header digital-credentials-get=(self) allows same-origin iframes.
+PASS Permissions-Policy header digital-credentials-get=(self) disallows cross-origin iframes.
+PASS Permissions-Policy header digital-credentials-get=(self) get overridden by allow attribute.
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html b/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html
new file mode 100644
index 0000000000000..a600be222aef6
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html.headers b/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html.headers
new file mode 100644
index 0000000000000..1207d9e29a111
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html.headers
@@ -0,0 +1 @@
+Permissions-Policy: digital-credentials-get=(self)
diff --git a/LayoutTests/imported/w3c/web-platform-tests/permissions-policy/resources/digital-credentials-get.html b/LayoutTests/imported/w3c/web-platform-tests/permissions-policy/resources/digital-credentials-get.html
new file mode 100644
index 0000000000000..90413c247b10f
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/permissions-policy/resources/digital-credentials-get.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+ Digital Credentials iframe
+
diff --git a/LayoutTests/platform/glib/TestExpectations b/LayoutTests/platform/glib/TestExpectations
index bf408c8e9b4f2..05d176746d470 100644
--- a/LayoutTests/platform/glib/TestExpectations
+++ b/LayoutTests/platform/glib/TestExpectations
@@ -2771,6 +2771,7 @@ imported/w3c/web-platform-tests/credential-management/ [ Skip ]
# Digital Crendentials API
http/wpt/identity/ [ Skip ]
+http/tests/identity/ [ Skip ]
imported/w3c/web-platform-tests/digital-credentials/ [ Skip ]
# WebGL2
diff --git a/LayoutTests/platform/mac-site-isolation/TestExpectations b/LayoutTests/platform/mac-site-isolation/TestExpectations
index 44577274a23d9..2ae2f6e77f962 100644
--- a/LayoutTests/platform/mac-site-isolation/TestExpectations
+++ b/LayoutTests/platform/mac-site-isolation/TestExpectations
@@ -5195,6 +5195,7 @@ http/wpt/html/semantics/scripting-1/the-script-element/module/module-meta-url-re
http/wpt/html/semantics/scripting-1/the-script-element/module/module-meta-url-with-fragment.html [ Skip ]
http/wpt/html/semantics/text-level-semantics/the-a-element/a-download-click-404.html [ Skip ]
http/wpt/identity/identitycredentialscontainer-create-basics.https.html [ Skip ]
+http/tests/identity/allow-attribute.https.html [ Skip ]
http/wpt/identity/identitycredentialscontainer-get-basics.https.html [ Skip ]
http/wpt/identity/identitycredentialscontainer-store-basics.https.html [ Skip ]
http/wpt/identity/idl.https.html [ Skip ]
diff --git a/LayoutTests/platform/mac-wk1/TestExpectations b/LayoutTests/platform/mac-wk1/TestExpectations
index 5ef95ed20b5a4..710b97aa65aab 100644
--- a/LayoutTests/platform/mac-wk1/TestExpectations
+++ b/LayoutTests/platform/mac-wk1/TestExpectations
@@ -1827,6 +1827,7 @@ imported/w3c/web-platform-tests/credential-management/ [ Skip ]
# Skip Digital Credentials API
http/wpt/identity/ [ Skip ]
+http/tests/identity/ [ Skip ]
imported/w3c/web-platform-tests/digital-credentials/ [ Skip ]
webkit.org/b/182554 transitions/transition-display-property.html [ Pass ImageOnlyFailure ]
diff --git a/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.h b/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.h
index 7b4d6fefcd43a..1320ede2d1456 100644
--- a/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.h
+++ b/Source/WebCore/Modules/credentialmanagement/CredentialsContainer.h
@@ -71,6 +71,7 @@ class CredentialsContainer : public RefCounted {
protected:
template
bool performCommonChecks(const Options&, CredentialPromise&);
+ const Document* document() const { return m_document.get(); }
};
} // namespace WebCore
diff --git a/Source/WebCore/Modules/identity/IdentityCredentialsContainer.cpp b/Source/WebCore/Modules/identity/IdentityCredentialsContainer.cpp
index c54ba6b841abb..271cd3b0d4182 100644
--- a/Source/WebCore/Modules/identity/IdentityCredentialsContainer.cpp
+++ b/Source/WebCore/Modules/identity/IdentityCredentialsContainer.cpp
@@ -48,6 +48,12 @@ void IdentityCredentialsContainer::get(CredentialRequestOptions&& options, Crede
if (!performCommonChecks(options, promise))
return;
+ RefPtr document = this->document();
+ if (!PermissionsPolicy::isFeatureEnabled(PermissionsPolicy::Feature::DigitalCredentialsGetRule, *document, PermissionsPolicy::ShouldReportViolation::No)) {
+ promise.reject(Exception { ExceptionCode::NotAllowedError, "Third-party iframes are not allowed to call .get() unless explicitly allowed via Permissions Policy (digital-credentials-get)"_s });
+ return;
+ }
+
if (!options.digital) {
promise.reject(Exception { ExceptionCode::NotSupportedError, "Only digital member is supported."_s });
return;
diff --git a/Source/WebCore/html/PermissionsPolicy.cpp b/Source/WebCore/html/PermissionsPolicy.cpp
index bf28929bbb422..a153088900d48 100644
--- a/Source/WebCore/html/PermissionsPolicy.cpp
+++ b/Source/WebCore/html/PermissionsPolicy.cpp
@@ -77,6 +77,8 @@ static ASCIILiteral toFeatureNameForLogging(PermissionsPolicy::Feature feature)
#if ENABLE(WEB_AUTHN)
case PermissionsPolicy::Feature::PublickeyCredentialsGetRule:
return "PublickeyCredentialsGet"_s;
+ case PermissionsPolicy::Feature::DigitalCredentialsGetRule:
+ return "DigitalCredentialsGet"_s;
#endif
#if ENABLE(WEBXR)
case PermissionsPolicy::Feature::XRSpatialTracking:
@@ -117,6 +119,7 @@ static std::pair readFeatureIdentifier(S
#endif
#if ENABLE(WEB_AUTHN)
constexpr auto publickeyCredentialsGetRuleToken { "publickey-credentials-get"_s };
+ constexpr auto digitalCredentialsGetRuleToken { "digital-credentials-get"_s };
#endif
#if ENABLE(WEBXR)
constexpr auto xrSpatialTrackingToken { "xr-spatial-tracking"_s };
@@ -171,6 +174,9 @@ static std::pair readFeatureIdentifier(S
} else if (value.startsWith(publickeyCredentialsGetRuleToken)) {
feature = PermissionsPolicy::Feature::PublickeyCredentialsGetRule;
remainingValue = value.substring(publickeyCredentialsGetRuleToken.length());
+ } else if (value.startsWith(digitalCredentialsGetRuleToken)) {
+ feature = PermissionsPolicy::Feature::DigitalCredentialsGetRule;
+ remainingValue = value.substring(digitalCredentialsGetRuleToken.length());
#endif
#if ENABLE(WEBXR)
} else if (value.startsWith(xrSpatialTrackingToken)) {
@@ -213,6 +219,7 @@ static ASCIILiteral defaultAllowlistValue(PermissionsPolicy::Feature feature)
#endif
#if ENABLE(WEB_AUTHN)
case PermissionsPolicy::Feature::PublickeyCredentialsGetRule:
+ case PermissionsPolicy::Feature::DigitalCredentialsGetRule:
#endif
#if ENABLE(WEBXR)
case PermissionsPolicy::Feature::XRSpatialTracking:
diff --git a/Source/WebCore/html/PermissionsPolicy.h b/Source/WebCore/html/PermissionsPolicy.h
index e5c8e0fdbf760..4f8160afa9fdf 100644
--- a/Source/WebCore/html/PermissionsPolicy.h
+++ b/Source/WebCore/html/PermissionsPolicy.h
@@ -62,6 +62,7 @@ class PermissionsPolicy {
#endif
#if ENABLE(WEB_AUTHN)
PublickeyCredentialsGetRule,
+ DigitalCredentialsGetRule,
#endif
#if ENABLE(WEBXR)
XRSpatialTracking,