[Bug] gemini-enterprise time-based access: the configured time zone is not honored — a re-run silently resets it to America/New_York, and the level's title and hour descriptions assert Eastern regardless of what was set
Maintainers usually reply within 2 days
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 58/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Quiet
- Tech stack
- shell, terraform
- Domain
- cloud, infrastructure, security
Research direction
Start with deploy.sh:1143-1180 and 2455-2469 to trace the preserving branches and tfvars writes, then inspect gemini-stage-0/variables.tf:102-110 and access_policy.tf:44-53. Re-run the deployment and use the issue's gcloud access-context-manager command to compare the configured values before and after. Done means the configured timezone and window survive re-runs, labels describe them accurately, and the expire branch no longer resets its value.
Written by the indexing model from the issue text.
Description
Bug Description
Three defects in the same feature, all of which make a non-Eastern deployment look and behave as Eastern. They share ten lines of code, so they are reported together; splitting them is fine if preferred.
1. The hour variables are documented as Eastern, unconditionally
# gemini-stage-0/variables.tf:102-110
variable "access_start_hour" {
description = "The hour (0-23) in America/New_York timezone when access starts."
}
variable "access_end_hour" {
description = "The hour (0-23) in America/New_York timezone when access ends."
}
Both descriptions name America/New_York as the timezone the hour is expressed in. That is only true when access_time_zone is left at its default. The expression actually evaluates the hour in whatever access_time_zone is set to (access_policy.tf:51 — request.time.getHours("${var.access_time_zone}")), so for any other timezone the documentation is simply wrong about what the number means. An operator configuring America/Anchorage reads that access_start_hour = 8 is 8am Eastern; it is 8am Alaska.
2. The access level's title hardcodes Eastern
# gemini-stage-0/access_policy.tf:48
title = "Business Hours East Coast"
This never varies with access_time_zone. Anyone reading the level in the Console or via gcloud access-context-manager levels describe time sees "Business Hours East Coast" asserted over a window that may be Alaska, Pacific or anything else. Combined with defect 1, every user-facing surface of this feature claims Eastern while the evaluation is doing something different — which is precisely the state that makes a misconfiguration invisible.
To be clear about what is NOT broken: the CEL expression itself is correct. It substitutes var.access_time_zone into all four getHours / getDayOfWeek calls, so a level built from a fresh, complete run evaluates in the configured zone. The bug is that the labels and docs say otherwise — and defect 3 then throws the configured value away entirely.
3. "Preserving" silently overwrites the configured window with the defaults
When the time access level already exists and is Terraform-managed, deploy.sh reports that it is preserving it and skips every time-related prompt:
# deploy.sh:1143-1150
if echo "$EXISTING_LEVELS" | grep -qE "(/|^)time$"; then
if [[ "$MANAGED_ACCESS_LEVELS" == *"time"* ]]; then
echo -e "${GREEN}Found existing MANAGED Access Level 'time'. Preserving.${NC}"
CREATE_TIME_ACCESS="true"
else
echo -e "${YELLOW}Access Level 'time' already exists (Unmanaged). Skipping.${NC}"
CREATE_TIME_ACCESS="false"
fi
else
# the five prompts — start day, end day, start hour, end hour, TIME ZONE — live here
fi
Because the prompts are skipped, ACCESS_START_DAY, ACCESS_END_DAY, ACCESS_START_HOUR, ACCESS_END_HOUR and ACCESS_TIME_ZONE are all unset. They are never hydrated from prior state either — the only assignments to any of them in the whole script are the prompts at :1155-1164.
The tfvars writer then skips each one, because every write is guarded on the variable being non-empty:
# deploy.sh:2455-2469
if [[ -n "$ACCESS_START_DAY" ]]; then echo "access_start_day = ${ACCESS_START_DAY}" >> gemini-stage-0/terraform.tfvars; fi
...
if [[ -n "$ACCESS_TIME_ZONE" ]]; then echo "access_time_zone = \"${ACCESS_TIME_ZONE}\"" >> gemini-stage-0/terraform.tfvars; fi
So nothing is written, and Terraform falls back to the variable defaults — access_time_zone = "America/New_York", access_start_hour = 7, access_end_hour = 21, access_start_day = 1, access_end_day = 5.
Meanwhile CREATE_TIME_ACCESS="true" means the resource is still fully managed, and its expression is rebuilt from exactly those variables:
# gemini-stage-0/access_policy.tf:44-53
resource "google_access_context_manager_access_level" "time" {
count = var.access_policy_number != "" && var.create_time_access ? 1 : 0
title = "Business Hours East Coast"
custom { expr {
expression = ("request.time.getHours(\"${var.access_time_zone}\") >= ${var.access_start_hour} && ... <= ${var.access_end_day}")
}}
}
The apply therefore overwrites the operator's configured window with the East-Coast defaults, immediately after printing "Preserving." The script reports the opposite of what it does.
The expire level has the identical defect (deploy.sh:1173-1180): "Preserving" + CREATE_EXPIRE_ACCESS="true", no prompt, ACCESS_EXPIRATION_TIMESTAMP unset, not written, so the expiry silently resets to the default 2028-01-01T00:00:00Z. The us level shares the shape but carries no parameters, so nothing is lost there.
Environment and Deployment Context
- Stellar Engine Version/Commit:
mainat commitf64ce6cd(= tagv3.0.0), verified 2026-08-11 - Deployment Type:
- US Region Restricted (e.g., Access Policy constraint)
- FedRAMP Medium
- FedRAMP High
- FedRAMP Moderate
- DoD IL4
- DoD IL5
- Stand-alone / Custom
- FAST Stage (if applicable): N/A — this is a blueprint, not a FAST stage
- Stage 0 (Bootstrap)
- Stage 1 (Resource Management)
- Stage 2 (Network Creation)
- Stage 3 (Security and Audit)
- Affected Component:
blueprints/fedramp-high/gemini-enterprise/gemini-stage-0/variables.tf:102-110(hour descriptions hardcodingAmerica/New_York)blueprints/fedramp-high/gemini-enterprise/gemini-stage-0/access_policy.tf:48(title hardcodingBusiness Hours East Coast)blueprints/fedramp-high/gemini-enterprise/deploy.sh:1143-1150(the "Preserving" branch that skips the prompts)blueprints/fedramp-high/gemini-enterprise/deploy.sh:1155-1164(the only assignments to the five variables)blueprints/fedramp-high/gemini-enterprise/deploy.sh:2455-2469(writes guarded on non-empty)blueprints/fedramp-high/gemini-enterprise/deploy.sh:1173-1180(same defect forexpire)blueprints/fedramp-high/gemini-enterprise/gemini-stage-0/access_policy.tf:44-53(the managed resource)
- Terraform Version:
1.12.2(pinned bydeploy.shvia tfenv; the stage declaresrequired_version >= 1.7.4) - GCP Provider Version:
hashicorp/google >= 6.21.0(stage-0 declared constraint)
Steps to Reproduce
- Run
deploy.sh, answer y to time-based access, and set a non-default window — e.g. Time ZoneAmerica/Anchorage, start hour8, end hour18. - Complete the apply. Read the level back and confirm the expression carries
America/Anchorageand>= 8 && <= 18. - Run
deploy.shagain against the same environment — any second pass, which is the normal path for adding an application or re-running a stage. - Observe
Found existing MANAGED Access Level 'time'. Preserving.and note that no time prompts appear. - Complete the apply and read the level again:
gcloud access-context-manager levels describe time --policy <access_policy_number>.
Expected Behavior
The configured time zone is honored and represented consistently. Specifically: the hour descriptions say the hour is expressed in access_time_zone, not in America/New_York; the level's title reflects the configured zone rather than asserting Eastern; and "Preserving" preserves — either the existing values are read back and re-written unchanged, or the operator is re-prompted with them as defaults, or the resource is left unmanaged so Terraform does not touch it.
Actual Behavior
Every user-facing surface asserts Eastern regardless of configuration, and the configured value does not survive a second run:
access_start_hour/access_end_hourare documented as being "in America/New_York timezone" whateveraccess_time_zoneis set to.- The level is titled
Business Hours East Coastwhateveraccess_time_zoneis set to. - On any re-run through the wizard, the level is rewritten to the defaults: timezone reverts to
America/New_York, hours to07:00-21:00, days to Mon-Fri. For a deployment configured inAmerica/Anchoragethat shifts the effective window by four hours — an08:00-18:00Alaska window silently becomes07:00-21:00Eastern, i.e.03:00-17:00local. No warning, no prompt, and the console line says the opposite.
The net effect is that an operator who sets a non-Eastern zone has no surface anywhere — variable docs, level title, or a second wizard run — that agrees with what they configured.
Relevant Logs and Errors
No error is emitted — that is the defect. The only operator-visible signal is the line that misdescribes what happens:
--- Time Based Access ---
Found existing MANAGED Access Level 'time'. Preserving.
The resulting expression, rebuilt from the defaults:
request.time.getHours("America/New_York") >= 7 && request.time.getHours("America/New_York") <= 21 &&
request.time.getDayOfWeek("America/New_York") >= 1 && request.time.getDayOfWeek("America/New_York") <= 5
Suggested Fix
Defects 1 and 2 are one-liners. Change the access_start_hour / access_end_hour descriptions to say the hour is expressed in access_time_zone (naming America/New_York only as the default), and make the level title carry the configured zone — e.g. "Business Hours (${var.access_time_zone})" — instead of hardcoding East Coast.
Defect 3, in the "Preserving" branch, do one of:
- Read the existing level back and populate
ACCESS_*from it before the tfvars write, so the values round-trip; or - Re-prompt using the existing values as the defaults; or
- Set
CREATE_TIME_ACCESS="false"so Terraform stops managing a level the script has decided not to reconfigure — matching what "Preserving" already implies.
Whichever is chosen, the console message must match the behavior, and the same fix applies to the expire branch.
Additional Context
Found while running a deployment configured for America/Anchorage. Defect 3 is security-relevant rather than cosmetic: a time-based access control silently shifts its effective window on an ordinary re-run, and an operator who reads the "Preserving" line has no reason to re-check it. Defects 1 and 2 are what make it hard to catch — every label and description the operator can consult says Eastern, so the reset back to Eastern looks like the intended state.
Related: #186 covers the day-numbering mismatch in the same expression — the day prompts at deploy.sh:1155 / :1157 and the access_start_day / access_end_day descriptions all state 1=Mon, 7=Sun while CEL's getDayOfWeek() is 0-6. Between the two reports, every input to this one access level is either mis-documented or discarded on re-run; they are worth fixing together.
- Dominant language
- HCL
- Stars
- 51
- Forks
- 21
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 30
Getting set up
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from google/stellar-engine
-
documentation Level of Effort - High Priority - Medium
Difficulty 1/5 1-3 hours Newbie friendliness 88/100
google/stellar-engine#232 ·
Maintainers usually reply within 2 days
-
Bug Gemini - Government Level of Effort - Low Priority - Low
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
google/stellar-engine#135 ·
Maintainers usually reply within 2 days
-
[Feature Request] gem4gov: implement BigQuery import in the standalone datastore import commandOpenEnhancement Gemini - Government Level of Effort - Medium Priority - Medium
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
google/stellar-engine#122 ·
Maintainers usually reply within 2 days
-
documentation Level of Effort - Medium Priority - Medium
Difficulty 2/5 Half a day Newbie friendliness 72/100
google/stellar-engine#117 · 1 comment ·
Maintainers usually reply within 2 days
-
[Feature Request] No research blueprint family — the README names universities as a target audience, every blueprint is FedRAMP High, FedRAMP Moderate or IL5Possibly taken @Calvin-Cheng1 claimed this 19 days ago. Openenhancement
google/stellar-engine#239 · 2 comments · 1 assignee ·
Maintainers usually reply within 2 days
All issues in google/stellar-engine
Similar issues
-
area: providers/aws priority: p2 size: S type: bug
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
finos/open-resource-broker#418 · 1 comment ·
Maintainers usually reply within 1 day
-
GCP region parser selects the wrong region for multi-digit region numbersPossibly taken @nawaaaaaAaar claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
mlco2/codecarbon#1438 ·
Maintainers usually reply within 1 day
-
bug needs-triage service/agentregistry
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
hashicorp/terraform-provider-aws#50277 · 1 comment ·
Maintainers usually reply within 1 day
-
enhancement internal-synced
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
azureblob: sync at the account root fails on soft deleted containers and deletes nothingPossibly taken @LudovicBondon claimed this today. Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 3 days