Pesquisar

Announcement
· 21 hr ago

CCR Application Improvements for Best Practices

Over the last year, the CCR development team has prioritized changes to the CCR application to better expose and encourage best practices for using CCR. This article will highlight some of the areas that we've focused on:

  • Organization Dashboard
  • System Alerts
  • Branch Hygiene

In each of these areas, we have increased the visibility of potential CCR usage issues and given users tools to proactively address them.

Organization Dashboard

We have continued to build out the available information on the Organization details page

The overview is a great place to get an overall sense of your Organization's CCR usage. It now includes more KPIs highlighting various concerns and linking to the pages in the CCR application where you can address them. 

The Systems tab includes detailed information about the state of Client Tools across all Environments as well as System Architect information. The alerts here highlight missing information, inactivity, and out of date Client Tools, with links to the corresponding Systems.

Other tabs on the Organization details page have been enhanced with additional details to make your Organization's CCR usage clear at a glance.

System Alerts

Another area of improved visibility is the System details page, where we now have alerts for many CCR usage issues.

Environment alerts have been added for unset URLs, insecure URLS, and detected Client Tools issues. Details are displayed on hover:

When CCR detects that the Client Tools are out of date for the System, an alert will appear to encourage the use of the update button.

Systems that have had no activity for 6 months will now display an alert.  Such a System can be deprecated if it is no longer in use, or the snooze button can be clicked here to count this as an active System for the next year. This is appropriate for some types of Systems that rarely need to receive updates.

System Branch Hygiene

System Branch Hygiene is a powerful tool for understanding existing issues in a System's Perforce branches. It is available on the System details page for each Tier 1 or 2 System.

Core functionality of the tool has been in place for some time, but recent enhancements have improved detection of some edge cases.

Running this check on a mature System is a great way to identify any items that may cause problems in the future.

Conclusion

In these areas and across the CCR application, there have been many changes this year with the goal of promoting the best usage of CCR. Future improvements will focus on further exposing information and developing tools that help users of CCR to better understand their Systems and address issues proactively.

If you have any questions or suggestions for ways that the CCR application can encourage best practices, please let us know at ccrdev@intersystems.com.

Discussion (0)1
Log in or sign up to continue
InterSystems Official
· Jan 15

IPM Version 0.10.5 Release Notes

IPM version 0.10.5 has been released on January 15, 2026. This new version contains a ton of improvements and bug fixes so be sure to check it out either directly from the GitHub page or from the Community Registry!

The big changes include the following:

  • A rewrite of dependency resolution that drastically improves performance, including a 200x speed increase in very complicated cases
  • A History Log that tracks the IPM installs, loads, updates, and uninstalls that can be viewed using zpm "log" 
  • System expressions, like ${namespace}, and $$$ macros are now evaluated in CPF merge files allowing for more initial configuration flexibility
  • <Invoke> in module.xml behaves more intuitively by always checking the %Status return value if and only if the method signature declares %Status is returned. This means an error will be thrown if nothing is returned, the return value is not a %Status, or it is not $$$OK.

Here's the full changelist:

Added

  • #938: Added flag -export-python-deps to package command
  • #462: The repo command for repository configuration now supports secret input terminal mode for passwords with the -password-stdin flag
  • #935: Adding a generic JFrog Artifactory tarball resource processor for bundling artifact with a package and deploying it to a final location on install.
  • #950: Added support for listing installed Python packages using list -pythonlist -py and list-installed -python
  • #822: The CPF resource processor now supports system expressions and macros in CPF merge files
  • #578: Added functionality to record and display IPM history of install, uninstall, load, and update
  • #961: Adding creation of a lock file for a module by using the -create-lockfile flag on install.
  • #959: In ORAS repos, external name can now be used interchangeably with (default) name for install and update, i.e. a module published with its (default) name can be installed using its external name.
  • #951: The unpublish command will skip user confirmation prompt if the -force flag is provided.
  • #1018: Require module name for uninstall when not using the -all flag

Changed

  • #316: All parameters, except developer mode, included with a loadinstall or update command will be propagated to dependencies
  • #885: Always synchronously load dependencies and let each module do multi-threading as needed to load using multicompile instead of trying to do own multi-threading of item load which causes lock contention by bypassing IRIS compiler.
  • #481: Improve BuildDependencyGraph performance by doing the following:
    • Eliminate recursion and use iteration.
    • Remove depth first search and do pure breadth first search.
    • Have better caching of results for module searches by collapsing search expressions (reducing expressions that are intersections).

Removed

  • #938: Removed secret flag NewVersion handling in %Publish()

Fixed

  • #943: The load command when used with a GitHub repository URL accepts a branch argument again
  • #701: Fix misleading help comments about search command
  • #958: Update command should not fail early if external name is used
  • #970: fix: Resolve error in 'generate' command WebApp processing
  • #965: FileCopy on a directory with a Name without the leading slash now works
  • #937: Publishing a module with a <WebApplication> containing a Path no longer errors out
  • #957: Improved error messages for OS command execution. Now, when a command fails, the error message includes the full command and its return code. Also fixed argument separation for the Windows attrib command and removed misleading error handling for missing commands.
  • #789: Fix error when listing modules for an ORAS repo with a specified namespace.
  • #999, #1000: Installing IPM cleans up stale mappings used in old versions of IPM
  • #1007: The ${ipmDir} expression now works in the <Arg> of an <Invoke>
  • #1015: Fix dependency resolution bugs where * as the version requirement and intersecting ranges wouldn't work properly.
  • #1036: The update command no longer propagates developer mode to dependencies

Deprecated

  • #828: The CheckStatus flag for <Invoke> action has been deprecated. Default behavior is now to always check the status of the method if and only if the method signature returns %Library.Status
  • #885: -synchronous flag since loading dependencies synchronously is now the default behavior.

Security

  • urllib3 wheel has been updated to 2.6.3

 

If you have any questions, suggestions, or bugs you'd like to raise, feel free to bring them up here or on the GitHub page. (On GitHub, questions and suggestions should go to the discussions page, and bugs should go to the issues page.)

1 new Comment
Discussion (1)3
Log in or sign up to continue
Question
· Jan 15

VsCode error to create a new class definition.

Anyone else is passing through this issue?

Since last week when I create a new class definition, It is created without the full name into the signature class and I have to put it by myself.

I thougth that should be any configuration about the language patterns, but I didn`t found it.



Thank you all

2 new Comments
Discussion (2)2
Log in or sign up to continue
Article
· Jan 15 3m read

Generando JWT sin acceso a los certificados/keys x509 del sistema

Si queréis generar JWT a partir de un certificado/clave x509, cualquier operación (incluida la lectura) sobre %SYS.X509Credentials requiere el permiso U en el recurso %Admin_Secure. Esto se debe a que %SYS.X509Credentials es persistente y está implementado así para evitar que todos los usuarios tengan acceso a las claves privadas.

Si el recurso %Admin_Secure no está disponible en tiempo de ejecución, podéis usar la siguiente solución alternativa.

Revisándo el código de generación de JWT, descubrí que sólo utiliza %SYS.X509Credentials como fuente de datos en tiempo de ejecución para PrivateKey, PrivateKeyPasswordy Certificate. Como alternativa, podéis usar una implementación no persistente en tiempo de ejecución de la interfaz X.509, exponiendo únicamente estas propiedades.

Si estáis usando interoperabilidad, el certificado/clave privada se puede almacenar en credenciales para un acceso seguro.

Class User.X509 Extends %RegisteredObject
{

Property PrivateKey As %VarString;
Property PrivateKeyPassword As %String;
Property Certificate As %VarString;
Property HasPrivateKey As %Boolean [ InitialExpression = {$$$YES} ];
ClassMethod GetX509() As User.X509
{
    set x509 = ..%New()
    set x509.PrivateKey = ..Key()
    set x509.Certificate = ..Cert()
    quit x509
}

/// Get X509 object from credential.
/// Username is a Cert, Password is a Private Key
ClassMethod GetX509FromCredential(credential) As User.X509
{
    set credentialObj = ##class(Ens.Config.Credentials).%OpenId(credential,,.sc)
    throw:$$$ISERR(sc) ##class(%Exception.StatusException).ThrowIfInterrupt(sc)
    
    set x509 = ..%New()
    set x509.PrivateKey = credentialObj.Password
    set x509.Certificate = credentialObj.Username
    quit x509
}

ClassMethod Key()
{
    q "-----BEGIN RSA PRIVATE KEY-----"_$C(13,10)
    _"YOUR_TEST_KEY"_$C(13,10)
    _"-----END RSA PRIVATE KEY-----"
}

ClassMethod Cert() As %VarString
{
    q "-----BEGIN CERTIFICATE-----"_$C(13,10)
    _"YOUR_TEST_CERT"_$C(13,10)
    _"-----END CERTIFICATE-----"
}

}

Y podéis generar JWT de la siguiente manera:

ClassMethod JWT() As %Status
{
    Set sc = $$$OK
    //Set x509 = ##class(%SYS.X509Credentials).GetByAlias("TempKeyPair")
    Set x509 = ##class(User.X509).GetX509()
    
    Set algorithm ="RS256"
    Set header = {"alg": (algorithm), "typ": "JWT"}
    Set claims= {"Key": "Value" }
    
    #; create JWK
    Set sc = ##class(%Net.JSON.JWK).CreateX509(algorithm,x509,.privateJWK)
    
    If $$$ISERR(sc) {
        Write $SYSTEM.OBJ.DisplayError(sc)
    }

    #; Create JWKS
    Set sc = ##class(%Net.JSON.JWKS).PutJWK(privateJWK,.privateJWKS)
    
    If $$$ISERR(sc) {
        Write $SYSTEM.OBJ.DisplayError(sc)
    }

    Set sc = ##Class(%Net.JSON.JWT).Create(header,,claims,privateJWKS,,.pJWT)
    
    If $$$ISERR(sc) {
        Write $SYSTEM.OBJ.DisplayError(sc)
    }
    
    Write pJWT
	Return sc
}

Alternativamente, podéis usar un objeto dinámico para evitar crear la clase; en ese caso, se vería así:

ClassMethod JWT(credential) As %Status
{
    Set sc = $$$OK
    //Set x509 = ##class(%SYS.X509Credentials).GetByAlias("TempKeyPair")
    Set credentialObj = ##class(Ens.Config.Credentials).%OpenId(credential,,.sc)
    throw:$$$ISERR(sc) ##class(%Exception.StatusException).ThrowIfInterrupt(sc)
    
    Set x509 = {
        "HasPrivateKey": true,
        "PrivateKey": (credentialObj.Password),
        "PrivateKeyPassword":"",
        "Certificate":(credentialObj.Username)
    }

    Set algorithm ="RS256"
    Set header = {"alg": (algorithm), "typ": "JWT"}
    Set claims= {"Key": "Value" }
    
    #; create JWK
    Set sc = ##class(%Net.JSON.JWK).CreateX509(algorithm,x509,.privateJWK)
    
    If $$$ISERR(sc) {
        Write $SYSTEM.OBJ.DisplayError(sc)
    }

    #; Create JWKS
    Set sc = ##class(%Net.JSON.JWKS).PutJWK(privateJWK,.privateJWKS)
    
    If $$$ISERR(sc) {
        Write $SYSTEM.OBJ.DisplayError(sc)
    }

    Set sc = ##Class(%Net.JSON.JWT).Create(header,,claims,privateJWKS,,.pJWT)
    
    If $$$ISERR(sc) {
        Write $SYSTEM.OBJ.DisplayError(sc)
    }
    
    Write pJWT
    Return sc
}
Discussion (0)1
Log in or sign up to continue
Announcement
· Jan 15

[Video] ¿Qué es el InterSystems Secure Wallet?

Hola Comunidad!

¿Necesitas un modo de almacenar de forma segura tus passwords, API keys y otras credenciales? Mira como el Secure Wallet en InterSystems IRIS® data platform te puede ayudar:

¿Qué es el InterSystems Secure Wallet?

En este video, verás como utilizar Secure Wallet para almacenar y gestionar, de forma segura, credenciales utilizadas por aplicaciones que se conectan a sistemas o fuentes de datos externas.

Discussion (0)1
Log in or sign up to continue