Skip to content

Commit 6fd6337

Browse files
Liubov Dmitrievameta-codesync[bot]
authored andcommitted
Add pre-minted CATs support for EdenAPI authentication
Summary: Teach the `[cats]` config consumer to use the `platform_cats_lib` preminted library when the winning config group is named `"preminted"` (set by `dynamic_system.rs` when `ATLAS=1`). The preminted file is a multi-token JSON blob keyed by verifier name (verify_integrity, interngraph, crypto_auth_tokens, …). The old `File::open` + `serde_json` path only extracts the `crypto_auth_tokens` key. By routing through `read_merged_preminted_cats_for()` we get a single merged token containing both verify_integrity and interngraph — exactly what Mononoke/EdenAPI needs. Behaviour per config group: * **"preminted"** (Dev Docker Images, priority 60): - File present → preminted library → merged tokens. - File missing → expected during lease provisioning; debug log, fall through to `try_preminted_cats()` fallback (which also returns `None`), auth degrades to X.509 certs. * **"sandcastle"** (priority 50) / other groups: - File present → old `File::open` + JSON parse → crypto_auth_tokens. - File missing → error propagated to caller. * **No config groups at all:** - `try_preminted_cats()` is tried as a final fallback. Reviewed By: muirdm Differential Revision: D95043384 fbshipit-source-id: 014c59f812db3e1cf1e8e04de6e8c998106a7c26
1 parent bedcf06 commit 6fd6337

2 files changed

Lines changed: 79 additions & 8 deletions

File tree

eden/scm/lib/cats/BUCK

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
load("@fbcode_macros//build_defs/lib:rust_oss.bzl", "rust_oss")
12
load("@fbsource//tools/build_defs:rust_library.bzl", "rust_library")
23

34
oncall("sapling")
@@ -25,5 +26,10 @@ rust_library(
2526
"fbsource//third-party/rust:tracing",
2627
"//eden/scm/lib/config/model:configmodel",
2728
"//eden/scm/lib/util:util",
28-
],
29+
] + select({
30+
"DEFAULT": [],
31+
"ovr_config//os:linux": ([] if rust_oss.is_oss_build() else [
32+
"//devinfra/lib/rust/platform_cats:platform_cats_lib",
33+
]),
34+
}),
2935
)

eden/scm/lib/cats/src/lib.rs

Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* LICENSE file in the root directory of this source tree.
66
*/
77

8+
#![allow(unexpected_cfgs)]
9+
810
// [cats]
911
// entry_name.priority=20
1012
// entry_name.path=/var/boo/cat
@@ -143,17 +145,80 @@ impl<'a> CatsSection<'a> {
143145
}
144146

145147
pub fn get_cats(&self) -> Result<Option<String>> {
146-
if let Some(cats_group) = self.find_cats()? {
147-
if let Some(path) = cats_group.path {
148-
let f = std::fs::File::open(path)?;
149-
let reader = std::io::BufReader::new(f);
148+
match self.find_cats() {
149+
Ok(Some(cats_group)) => {
150+
// The "preminted" config group (Dev Docker Images) uses a
151+
// multi-token file format. Use the preminted library to get
152+
// merged tokens (verify_integrity + interngraph) instead of
153+
// just the crypto_auth_tokens key from the JSON blob.
154+
#[cfg(all(fbcode_build, target_os = "linux"))]
155+
if cats_group.name == "preminted" {
156+
tracing::debug!("config group 'preminted'; using preminted CATs library");
157+
return Self::try_preminted_cats();
158+
}
150159

151-
let cats: Cats = serde_json::from_reader(reader)?;
152-
let cats_data = cats.crypto_auth_tokens;
160+
if let Some(path) = cats_group.path {
161+
let f = std::fs::File::open(&path)?;
162+
let reader = std::io::BufReader::new(f);
163+
let cats: Cats = serde_json::from_reader(reader)?;
164+
return Ok(Some(cats.crypto_auth_tokens));
165+
}
166+
}
167+
Ok(None) => {}
168+
Err(e) => {
169+
// If all configured groups are "preminted" (Dev Docker Images),
170+
// a missing file is expected during container lease provisioning.
171+
// For other groups (e.g. sandcastle), propagate the error.
172+
if self.groups.iter().all(|g| g.name == "preminted") {
173+
tracing::debug!("pre-minted CATs file not yet available: {e}");
174+
} else {
175+
return Err(e.into());
176+
}
177+
}
178+
}
179+
180+
// Config-based CATs not available; try pre-minted as fallback.
181+
Self::try_preminted_cats()
182+
}
153183

154-
return Ok(Some(cats_data));
184+
#[cfg(all(fbcode_build, target_os = "linux"))]
185+
fn try_preminted_cats() -> Result<Option<String>> {
186+
let wanted_keys: &[&str] = &[
187+
platform_cats_lib::CAT_KEY_VERIFY_INTEGRITY,
188+
platform_cats_lib::CAT_KEY_INTERNGRAPH,
189+
];
190+
191+
// Check if any pre-minted CATs exist on this machine.
192+
let all_cats = platform_cats_lib::read_all_preminted_cats();
193+
if all_cats.is_empty() {
194+
return Ok(None);
195+
}
196+
197+
// Pre-minted CATs exist — check if our required keys are present.
198+
let missing: Vec<&str> = wanted_keys
199+
.iter()
200+
.filter(|k| !all_cats.contains_key(**k))
201+
.copied()
202+
.collect();
203+
204+
if !missing.is_empty() {
205+
tracing::debug!(
206+
?missing,
207+
"pre-minted CATs available; some requested keys absent (X.509 will be used for those)"
208+
);
209+
}
210+
211+
match platform_cats_lib::read_merged_preminted_cats_for(wanted_keys) {
212+
Some(cats) => {
213+
tracing::debug!("using pre-minted CATs for authentication");
214+
Ok(Some(cats))
155215
}
216+
None => Ok(None),
156217
}
218+
}
219+
220+
#[cfg(not(all(fbcode_build, target_os = "linux")))]
221+
fn try_preminted_cats() -> Result<Option<String>> {
157222
Ok(None)
158223
}
159224
}

0 commit comments

Comments
 (0)