You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R targets流水线中加密密钥被判定过期的问题及解决方法咨询

解决targets包中加密数据流水线的密钥过期与存储问题

问题核心

用targets构建流水线时,全局加载的cyphr密钥会被targets判定为“新对象”,导致所有依赖它的target每次都重跑;将密钥设为target时,又因targets不支持cyphr密钥对象的默认存储格式报错。


可行解决方案

方案1:在Target内部加载密钥,避免全局依赖追踪

直接在需要密钥的target代码块内加载密钥,让targets仅追踪密钥文件本身而非内存中的密钥对象,从根源避免过期误判。

修改后的_targets.R代码:

library(targets)
library(tarchetypes)
library(cyphr) 
library(here) 

redcap_data_path <- here("./data/redcap_data.RDS")
key_dir <- here("./")

list(
  tar_target(redcap_data, {
    # 仅在target运行时加载密钥,不暴露为全局对象
    key <- cyphr::data_key(key_dir, path_user = key_dir)
    cyphr::decrypt(readRDS(redcap_data_path), key = key)
  }),
  tar_target(processed_data,
    some_function_to_process_data(redcap_data)
  )
) |> 
  tar_hook_outer(hook = encrypt_object(.x, key = cyphr::data_key(key_dir, path_user = key_dir))) |>
  tar_hook_inner(hook = decrypt_object(.x, key = cyphr::data_key(key_dir, path_user = key_dir)))

方案2:序列化密钥为RDS,指定Target存储格式

提前将密钥序列化保存为RDS文件,再在target中加载并指定format = "rds",解决targets无法存储cyphr密钥对象的问题。

  1. 先手动运行一次密钥序列化(仅需执行一次):
key <- cyphr::data_key(here("./"), path_user = here("./"))
saveRDS(key, here("./key.rds"))
  1. 修改_targets.R:
library(targets)
library(tarchetypes)
library(cyphr) 
library(here) 

redcap_data_path <- here("./data/redcap_data.RDS")

list(
  tar_target(encryption_key,
    readRDS(here("./key.rds")),
    format = "rds" # 强制用RDS格式存储密钥对象
  ),
  tar_target(redcap_data,
    cyphr::decrypt(readRDS(redcap_data_path), key = encryption_key),
    format = "rds"
  ),
  tar_target(processed_data,
    some_function_to_process_data(redcap_data)
  )
) |> 
  tar_hook_outer(hook = encrypt_object(.x, key = encryption_key)) |>
  tar_hook_inner(hook = decrypt_object(.x, key = encryption_key))

方案3:用环境变量传递密钥路径,简化钩子逻辑

将密钥路径存入环境变量,在钩子函数内部动态加载密钥,避免全局对象被targets追踪。

修改后的_targets.R代码:

library(targets)
library(tarchetypes)
library(cyphr) 
library(here) 

# 密钥路径存入环境变量,不生成全局密钥对象
Sys.setenv("ENCRYPTION_KEY_DIR" = here("./"))

list(
  tar_target(redcap_data,
    readRDS(here("./data/redcap_data.RDS"))
  ),
  tar_target(processed_data,
    some_function_to_process_data(redcap_data)
  )
) |> 
  tar_hook_outer(hook = encrypt_object(.x, key = cyphr::data_key(Sys.getenv("ENCRYPTION_KEY_DIR"), path_user = Sys.getenv("ENCRYPTION_KEY_DIR")))) |>
  tar_hook_inner(hook = decrypt_object(.x, key = cyphr::data_key(Sys.getenv("ENCRYPTION_KEY_DIR"), path_user = Sys.getenv("ENCRYPTION_KEY_DIR"))))

内容的提问来源于stack exchange,提问作者fluxthis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 16:22:32