gdbarron / venafitppps Goto Github PK
View Code? Open in Web Editor NEWDeprecated, see VenafiPS project. PowerShell module to access the features of Venafi Trust Protection Platform REST API
License: MIT License
Deprecated, see VenafiPS project. PowerShell module to access the features of Venafi Trust Protection Platform REST API
License: MIT License
I'm using that command and I'm getting this (warning I think)
Get-TppObject: /MY_PATH/Modules/VenafiTppPS/1.2.5/Public/New-TppCertificate.ps1:225
Line |
225 | $response.CertificateDN | Get-TppObject
| ~~~~~~~~~~~~~
| Find all matching subordinate Distinguished Names failed; ObjectDoesNotExist.
I think it is a warning cause I'm getting the cert created OK although receiving this... Is it anything I can ignore then?
Hello @gdbarron I'm in same state but now in Version 19.4.0.3361 and throwing me same error
.local/share/powershell/Modules/VenafiTppPS/2.0.1/Private/Invoke-TppRestMethod.ps1:146
Line |
146 | … throw ('"{0} {1}: {2}' -f $_.Exception.Response.StatusCod …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| "400 : {"Error":"Password does not conform to complexity requirements."}
BTW, Im using this passphrase: rufFji$4MOYiEaACv@o72VyY
No way man :(
Creating issue from comment in #53 by @Saadi6
Just FYI - see below from 18.2 release notes. Looks like others had the same issue. I suggested having a test in your function to ensure inherited Master Admin permissions are not overwritten with lesser privileges. This change in v18.2 checks the same thing but it would still be worthwhile having this test in the function to cater for older version of TPP. Also, I'm unsure if below is applicable to permissions set via the API.
_Master Admins Permissions Changed
Beginning with release 18.2, Master Admins can no longer have their permissions accidentally or intentionally removed at certain portions of the policy tree. This change occurred because of the number of customers unintentionally making changes to the permissions of Master Admin accounts which resulted in a call to a Venafi Support Engineering to reverse the problem. Adding extra permissions to Master Admins causes considerable slow downs for Aperture, WebAdmin, and WhyCustom Reports created by that user. By completely removing the ability to change Master Admins permissions in subsets of the tree, all Master Admins will see an increased performance benefit. It is important to note that when managing permissions, it is still possible to add Master Admins to the permissions control for a specific object and its children, but those permissions assignments will be ignored._
Operating System: Windows 10
VenafiTppPS version: 20.2.0.5474
PowerShell version: 5.1.18362.752
Please see the attached script. When I utilize your wrapper with an API Key, the log is written. However, when I use an OAuth token, I get this error:
Otherwise - Just a shout out. Your code saves me HOURS!!! Thanks for taking a look.
Hey @BeardedPrincess. Would you guys be open to using a Venafi/TPP icon with this module? Didn't want to use it without permission. Thanks.
Not a biggie, but something to consider: I think "Overwrite" should be the default mode of Set-TPPAttribute. Maybe change it to -NoClobber or -AddValue..
The reason is that ALL attributes can be multi-valued in TPP, even when it doesn't make sense. My fear is that people my inadvertently set multiple values to an attribute, which could have adverse affects on the processing of those objects.
I recently discovered this module, and am starting to test it out.
One of the first things I noticed was the Basic authentication that happens currently, albeit across an HTTPS session. So not insecure, but it isn't preferred IMO.
It looks like the newer versions of TPP (v17.3+) support Windows Authorization.
Could this new method be integrated into the New-TPPSession and underlying TPPSession class?
Here is a recent forum link about the method:
https://support.venafi.com/hc/en-us/community/posts/115000941452-Authorize
Again, I am still digesting and digging into this module, so currently excited to see what is available!
For some reason when associating a certificate with an application via new-tppobject in the platform itself the association doesn't show up. You have to remove the API created association and add it again.
Could we try to update Remove-TppCertificateAssociation to create a new Add-TppCertificateAssociation?
I have a need to actually download the certificate file (in pem or pfx) to the file system. My plan is to use this download feature to fetch a code signing or an SSL cert during build or deployment from Venafi, install it on the target, and then wipe the file. Would you be open to a PR which uses the /vedsdk/certificates/Retrieve endpoint to download the certificate file by using its distinguished name? From the looks of it, it appears I could use the Get-TppCertificateDetail to search by CommonName and obtain the distinguished name. If an entry is found, then use the /vedsdk/certificates/retrieve endpoint. If more than 1 entry is found, I suppose it could just throw a warning rather than fetch all of them.
@tristanbarcelon, I tried to assign this to you, but you didn't show up in the list.
Hi,
I have been using several of your functions, which are pretty incredible. It appears that the Find-TppCertificate function does not support offset but does support limit. See Venafi documentation for more information. Here is a screenshot of the doc.
Thanks for all the work you do.
Jeremy Meldrum
find-tppcertificate -createdafter "2020-10-1" returns all certs in the system not the 5 that should be in that range
v19.3.2
Operating System: Windows 10
VenafiTppPS version: 1.0.0 VenafiTppPS PSGallery
PowerShell version: PSVersion 5.1.18362.1110
Is it possible to use your module to import existing certificates? Looks like from the SDK that would be "POST Certificates/Import" and/or "POST Discovery/Import". I am looking to import existing Base64 certificates (no private keys available), followed by manually setting them as User Certificate type (this part I haven't found in the SDK on how to manually set).
Before I go down the rabbit hole of coding this without using your module, I figured it would be worth posting and asking.
Thanks in advance for all your great work!
Hi Greg,
Installed the 1.2.0 update today, but get an error right away when attempting to create a session.
$cred = Get-Credential
New-TppSession -ServerUrl https://venafi.mydomain.com -Credential $cred
Invoke-TppRestMethod : The term 'Invoke-TppRestMethod' is not recognized as the name of a cmdlet, function, script
file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct
and try again.
At C:\Users\myUsername\Documents\WindowsPowerShell\Modules\venafitppps\1.2.0\Class\TppSession.ps1:78 char:21
+ $response = Invoke-TppRestMethod @params
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Invoke-TppRestMethod:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
I removed the module from powershell, then deleted the 1.2.0 folder from my system. Re-imported the module and was able to log in via 1.1.0
Thanks,
Mark
If you're pipelining multiple objects into Get-TppCertificate and you use an option like -IncludePrivateKey, you get an error where you are trying to "re-add" the key to the hashtable. I think you need to re-initialize the params hash in process{}
Hi @gdbarron ,
Our security admins recently updated our Venafi server to 18.4. I recall that you had made changes for 18.3 in 0.7.3 but this version is unable to connect. Switching back to 0.7.2 works. Likewise, I'm also able to invoke Get-TppCertificate successfully on 0.7.2. I get an error like this on 0.7.3 with the Verbose switch on. I will dig deeper next week when I have available time. I suspect the issue the error has to do with changes to TppSession class and the switch to SystemStatus instead of SystemStatus/Version.
Invoke-RestMethod : {"Error":"Internal error occurred."}
At C:\Program Files\WindowsPowerShell\Modules\venafitppps\0.7.3\Private\Invoke-TppRestMethod.ps1:105 char:9
+ Invoke-RestMethod @params
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
Set-TppAttribute -Path $absolutepath -AttributeName 'Validity Period' -Value '3'
Putting different values... but it is always setting this value to 1, so it is not working. Can you help on this?
Regards
Hello, have been using this amazing module since 1 month. Now I need to get the status of the cert and I'm not being able to. Can you help on this please @gdbarron ?
Thanks in advance
Getting identity info has been added via browse and self. @Saadi6, can you help me understand why you suggested another function to filter these results as opposed to providing a more unique value, eg. email address, up front? Thanks.
Starting with TPP 20.1, the old way of getting and using the API key is being deprecated. In 20.4 /authorize will be disabled completely.
The new method for token-based authentication is much more efficient, but brings a bit of complexity with it unfortunately. The documentation covers quite a bit of this, including some design patterns starting here: https://docs.venafi.com/Docs/20.1SDK/TopNav/Content/SDK/AuthSDK/t-SDKa-OAuthConversionDesignPatterns.php
Opening this issue to start tracking this for the project. I'll also make myself available to assist (will try and get a PR submitted in the next week or so to get us rolling).
When associating a certificate to an application object (like a CAPI object) for provisioning, it is necessary to populate both the 'Certificate' attribute on the application object (this is being done already) and also add the application object DN to the 'Consumers' attribute on the certificate object.
There are a few side-effects of not populating 'Consumers':
Also, you must take care to not simply do a '/config/write' to the 'Consumers' attribute on the certificate, as that would remove any existing associations if the certificate is being provisioned to multiple locations. To perform this operation, you should use '/config/AddDnValue'.
(Wrapping this logic into a function meant to perform this association might be better reused, in the event you ever want to associate an existing certificate to an existing application object. This is the New-TPPCertificateAssociation function I mentioned in issue #1 )
So I'm part of a team that has access to the API in our Venafi (v18.4.0.3063) environment, but we are not Master Admins. I'm running into a problem with the CredentialPath parameter of the New-TppCapiApplication function. I'm unable to use the global credentials set by the Admins because it says that the object doesn't exist... more specifically "Credential object not found". I can see the cred path when creating CAPI's via the web interface, so I know it is correct. I suspect that this is because of my access rights, so I was wondering if there was a workaround or a way to toss something like an "IsInherited" switch in there. Any ideas or help would be most appreciated.
It seems the current implementation is using the ValidUntil value returned from the New-TPPSession to track how long the API key is valid for. This seems ok on the surface, but has a slight issue.
The ValidUntil is really more of a session-timeout. The API key is valid for 3 minutes. Every time a successful API query is made against TPP, the session ValidUntil gets reset to 3 minutes. So, checking the original ValidUntil may result in a re-authentication to TPP when one isn't necessary. (And authentication can be a pretty expensive operation on the TPP side, and should be minimized)
I'd recommend a couple of options. The first would be just to ignore the ValidUntil, and simply trap the specific error that will get thrown when the session times out inside of Invoke-TPPRestMethod. If the error is that the API key is invalid, simply re-auth at that point. The other option would be to update the ValidUntil inside Invoke-TPPRestMethod by calculating 150 seconds from now. (This is less than the 180 seconds that TPP will set, but gives a bit of buffer for timing etc.)
This project is shaping up nicely. I'm contemplating using it in some of my projects, but am curious on what license you're planning to release this under? Have I missed that documented somewhere?
I think this will be of particular interest to enterprise users as well.
Operating System: windows 10
VenafiTppPS version: 2.0.5
PowerShell version: 5.1.18362.1110
get-tppcertificatedetail -GUID 'anyguidID'
Expected get-tppcertificationdetail to provide field Description as per documentation
get-tppcertificationdetail is not returning description field anywhere (not even in the multivalue fields)
Provided text as institutional filters prevent image
PS C:\Users\bdoyle1> get-tppcertificatedetail -GUID 'e578ea89-adfc-445b-9cac-e297e1fb87b0'
Name : testcert.vfidev.com
TypeName : X509 Server Certificate
Path : \VED\Policy\Certificates\API\Requestor_Generated_CSR\testcert.vfidev.com
Guid : e578ea89-adfc-445b-9cac-e297e1fb87b0
ParentPath : \VED\Policy\Certificates\API\Requestor_Generated_CSR
Approver : {local:{53455e2e-9cb9-45f8-8c71-4d171a519b99}}
CertificateAuthorityDN : \VED\Policy\Administration\CAs\E3-Webserver-AFISubCA1
CertificateDetails : @{AIACAIssuerURL=System.Object[]; AIAKeyIdentifier=0C0EDEE39CE26573014B6107D1EB948AF8EFA297;
C=US; CDPURI=0::False:ldap:///CN=AFISubCA1(1),CN=MSPCSC12CCCA01,CN=CDP,CN=Public%20Key%20Servi
ces,CN=Services,CN=Configuration,DC=i,DC=ameriprise,DC=com?certificateRevocationList?base?obje
ctClass=cRLDistributionPoint; CN=testcert.vfidev.com; EnhancedKeyUsage=Client
Authentication(1.3.6.1.5.5.7.3.2),Server Authentication(1.3.6.1.5.5.7.3.1);
Issuer=CN=AFISubCA1, DC=i, DC=ameriprise, DC=com; KeyAlgorithm=RSA; KeySize=2048;
KeyUsage=KeyEncipherment, DigitalSignature; L=Minneapolis; O=Venafi; OU=System.Object[];
PublicKeyHash=C9D771D0E8660301066278CF3D4670DA9151BD3A; S=Minnesota;
SKIKeyIdentifier=366EB12D690EF927E9EB86EDDC0E4A1486F8A6F1;
Serial=2E00062D406F70FD4DC848CD6D000100062D40; SignatureAlgorithm=sha256RSA;
SignatureAlgorithmOID=1.2.840.113549.1.1.11; StoreAdded=2020-10-14T22:50:48.4748531Z;
Subject=CN=testcert.vfidev.com, OU=BizDev, O=Venafi, L=Minneapolis, S=Minnesota, C=US;
SubjectAltNameDNS=System.Object[]; TemplateMajorVersion=100; TemplateMinorVersion=36;
TemplateName=AFI-WebServer-AutoCreation; TemplateOID=1.3.6.1.4.1.311.21.8.6963390.1297995.1476
3659.10736412.8893591.125.13860656.4053856;
Thumbprint=FD7D6FB976CCF3C70438BCBD5ADFF10EB1C94E8C; ValidFrom=2020-10-14T22:40:48.0000000Z;
ValidTo=2022-10-14T22:40:48.0000000Z}
Contact : {local:{53455e2e-9cb9-45f8-8c71-4d171a519b99}}
CreatedBy : {Web SDK}
CreatedOn : 2020-10-14T22:50:46.0998415Z
ManagementType : Enrollment
ProcessingDetails :
RenewalDetails : @{City=Minneapolis; Country=US; KeySize=2048; Organization=Venafi;
OrganizationalUnit=System.Object[]; State=Minnesota; Subject=testcert.vfidev.com}
ValidationDetails : @{LastValidationStateUpdate=2020-10-15T00:00:07.0000000Z; ValidationState=Failure}
Hi @gdbarron. Why basic auth is not working now? I had changed my new-tppsession one liner and I'm getting this though
powershell/Modules/VenafiTppPS/2.0.0/Private/Invoke-TppRestMethod.ps1:136
"400 : {"Error":"Password does not conform to complexity requirements."}
It is not feasible that both methods can live together :D?
Hello, I was using this command at first
Get-TppCertificate -Path 'PATH' -Format 'OpenSSL' -OutPath 'PATH' -IncludePrivateKey -SecurePassword ($passphrase | ConvertTo-SecureString -asPlainText -Force)
but I got this error
Get-TppCertificate: Cannot validate argument on parameter 'Format'. The argument "Base64 (OpenSSL)" does not belong to the set "Base64,Base64 (PKCS #8),DER,JKS,PKCS #7,PKCS #12" specified by the ValidateSet attribute. Supply an argument that is in the set and then try the command again.
OK, just I use Base64 (this should be OpenSSL one by discard) and I'm getting this error
Format 'Base64' does not support private keys
I usually download like this (OpenSSL) with private key and passphrase through GUI and it works.
Can you help me on this please @gdbarron ? Thanks in advance
Implement Get-TppVersion. This helps the user know which functions are available. Add this to the session object so we can easily track.
Is it possible to add a SAN List to a new certificate request in any way?
Hi @gdbarron . The Identity/ReadAttribute method used by Get-TppIdentityAttribute function cannot read every attribute from the directory. My apologies for stating differently before - it was based on limited testing. While this method reads most of the attributes, not all of them return a value even when it exists in the directory. For e.g. ObjectSid, ObjectGUID, ObjectClass and ObjectCategory return a value but objectCategory returns null.
You may keep the inputs and validation of this function the same but note that it may or may not return a value, even when it is present in the directory or limit the choices of attributes to those present in the documentation.
I will let you know if I find out why TPP does not return values for some attributes.
Regards.
I've been working on this for awhile, its entirely possible that I am missing some prerequisites...but New-TPPCertificate doesn't actually seem to request a Cert from a CA?
Ran:
New-TppCertificate -Name $CommonName -Path $certpath -CertificateAuthorityPath $caprovider -ManagementType Provisioning
In my TPP console I see the new cert but the status is:
WebSDK CertRequest Module Requested Certificate
There is no CN, Organization, OU, City, State, Province and no CSR seems to have been sent to a CA?
Hello,
I'm getting this...
{@{Name=Owner Group; Type=Text; Value=System.Object[]}}
Instead of plain text value. Can you help me please... I would need to extract value from one field inside CustomFields
Thank you in advance
I wish I could provide more information, I'm still digging through why. I'm creating a type of "Apache" and it just straight up doesn't seem to try to push when I pass the -ProvisionCertificate flag.
Hi @gdbarron. To make it dead-simple for new users who are not that familiar with PowerShell, can you please add couple of lines to ReadeMe or docs on how to start using this module? It can be as simple as this:
Thanks!
Hi Greg,
This PowerShell module is awesome, Thanks for the contribution. I'm trying to build a custom scripted solution for an in-house app and have almost everything working, I'm able to use Get-TppCertificateDetail to collect a certificate's properties including DN, Expiration Date, Issuer, the list of SAN's and consumers (host names)
I'm stuck however on getting the list of contacts associated with the certificate. I'm using a foreach loop to parse through the list of UniversalIDs collecting the Name property of each contact.
$contacts = $CertProperties.Contact
$IDs = $null
foreach ($UniversalID in $contacts ) {
$IDs += (Get-TppIdentityAttribute -PrefixedUniversalId $UniversalID -TppSession $Session -Attribute Name | select -ExpandProperty Attribute).Name #line 101
$CertContacts += $IDs
$IDs
$UniversalID
}
Example output with error(s) below:
local:{ab92b6aa-0670-4070-8771-6eeb702d6beb}
Get-TppIdentityAttribute : Cannot validate argument on parameter 'PrefixedUniversalId'. The "
" validation script for the argument with value "AD+DOMAIN Forest:065380f0bb3e9847bba614e2f7718756" did not
return a result of True. Determine why the validation script failed, and then try the command again.
At C:\Scripts\Venafi\VenafiCertExpirationQuery2AppLogDebugv1.3.ps1:101 char:68
~~~~~~~~~~~~
AD+DOMAIN Forest:065380f0bb3e9847bba614e2f7718756
Get-TppIdentityAttribute : Cannot validate argument on parameter 'PrefixedUniversalId'. The "
" validation script for the argument with value "AD+DOMAIN Forest:0a7f39280f2b2444a1166bfe23288b77" did not
return a result of True. Determine why the validation script failed, and then try the command again.
At C:\Scripts\Venafi\VenafiCertExpirationQuery2AppLogDebugv1.3.ps1:101 char:68
~~~~~~~~~~~~
Of Note:
Thanks for your help.
John-
Hi all. I'm interested in implementing features which will be most useful to folks. Please let me know your thoughts! The SDK can be found https://docs.venafi.com/Docs/18.1SDK/TopNav/Content/SDK/WebSDK/API_Reference/c-REST-API-reference.php?tocpath=REST%20API%20reference%7C_____0.
@BeardedPrincess, mind chiming in?
Hi @gdbarron. Nice to see this project is still very much active!
Anyone using your libraries with multiple TPP servers may appreciate a method to Post informational/error messages to TPP's Log interface. TPP does log exit response from PowerShell scripts that are triggered by TPP engine itself but I find it useful to feed other pertinent information back into the logging engine while the script is executing, especially when interacting with other systems. If logged locally to disk, one has to hunt for the server which executed the script. This also has the added benefit of centralising enterprise-wide logging when TPP logs are being forwarded to a SIEM solution.
The method is POST Log. If an invalid value for ID is passed then the Event in the logs will not be matched to a component. For me, the params Component, Text1, Text2, SourceIp, Severity are plenty. Documentation is not entirely accurate - ID is required in my experience.
Thanks and appreciate your work!
I am trying to creating an adaptable App and an existing certificate to it and push it to vault.
The application gets created in the right place with an error output on line 105.
-ProvisionCertificate is not pushing the cert to Vault.
New-TppObject -ProvisionCertificate -Path ('{0}\standalonecert123.test.com' -f $devicepath) -Class 'Adaptable App' -Attribute @{'Driver Name'='appadaptable';'Certificate'=$certpath;'Text Field 2'='secrets/test/data/testing/pushtest'} -ProvisionCertificate
Test-TppObject: /home/user/.local/share/powershell/Modules/VenafiTppPS/1.2.3/Public/New-TppObject.ps1:105
Line |
105 | … if ( -not (Test-TppObject -Path (Split-Path $Path -Parent) -ExistO …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
| Cannot validate argument on parameter 'Path'. '/VED/Policy/Certificates/vcert/test-prod/vaultprod' is not a valid DN path
When using the various functions available in VenafiTppPS there can sometimes be a particular API call that is not available which would need a custom function setup. While TppSession info is available to use when adding this to a script, the 'Invoke-TppRestMethod' function is private and not available to use. It would be helpful to be able to use this to make the call to the Venafi API.
The current implementation of Get-TppCertificateDetail allows for the developer to specify a 'limit' parameter, but without the 'offset' parameter.
The idea is that Limit and Offset should be used together. As an example, if I had a query that returns 103 certificates, with a limit of 10, the first query would be offset 0, limit 10 to get the first 10 records. Then I'd check the total number of records, and decided that I need to fetch the next 10 using Limit 10, Offset 10. You can repeat until you have retrieved all the records.
My suggestion would be to eliminate exposing the offset to the user (it's confusing, and requires them to implement logic). Better would be to allow specifying the limit (as you have done), but detect the total number of records and make as many calls as necessary to return all of the results.
There is sample code implementing similar logic here: https://support.venafi.com/hc/en-us/articles/360001641051
You can export the private key in Base64 PKCS #8. Please remove this error check to disallow it.
@gdbarron when doing a clean install using 'Install-PSModule VenafiTPPPs', the Invoke-TPPRestMethod is imported in such a way that I can't establish a session.
Steps to repro:
Hi,
This is a request to add 2 new features.
Dissociate certificate - this feature will allow dissociating all applications from a cert.
My current process is:
get DN and GUID for a cert using Get-TppObject
$CertInfo = Get-TppObject -Pattern $FQDN -Recursive
$script:DN = $CertInfo.DN
$script:GUID = $CertInfo.GUID
get associated applications for the cert
$Attitubes = Get-TppAttribute -DN $DN -AttributeName "Consumers" -EffectivePolicy
$script:App = $Attitubes.config.value
use the $App array to disassociate the cert (bypassing your invoke-tpprequest):
$uri = ($TPPServer + '/vedsdk/Certificates/Dissociate')
$Method = 'POST'
$Body = @{
CertificateDN = $DN
ApplicationDN = $App
DeleteOrphans = 'true | false'
}
$restBody = ConvertTo-Json $Body -depth 5
$hdr = @{
"X-Venafi-Api-Key" = $TppSession.ApiKey
}
$params = @{
Method = $Method
Uri = $uri
Headers = $hdr
Body = $restBody
ContentType = 'application/json'
}
Write-Verbose ($params | ConvertTo-Json | out-string)
try {
$request = Invoke-RestMethod @params
....
Delete certificate - once all associations have been removed:
The DELETE Certificates/{guid} will also remove the associations, but as I wanted that as a standalone option (for use when not deleting a cert), I am calling it first.
$uri = ($TPPServer + '/vedsdk/Certificates/' + $GUID)
$Method = 'DELETE'
$hdr = @{
"X-Venafi-Api-Key" = $TppSession.ApiKey
}
$params = @{
Method = $Method
Uri = $uri
Headers = $hdr
ContentType = 'application/json'
}
Write-Verbose ($params | ConvertTo-Json | out-string)
try {
$request = Invoke-RestMethod @params
...
thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.